在bash脚本中获取所有args,同时只需要特定的字符串

时间:2016-05-12 16:35:57

标签: bash case args

我有一个名为manp的bash脚本,它有一些案例选项,如下所示:

ARGS=$@

while [[ $# -gt 0 ]] ; do
    case "$1" in
        --log)
            LOG=1
            shift
            ;;
        --upgrade*)
            UPGRADE=1
            echo "$ARGS"              # Outputs --upgrade tclclean==2.1 pms ubu==2.2
            PCKG_INFO=${ARGS#*\ }    # Supposed to strip everything before the space in front of tclclean
            shift
            ;;
        -*|*) 
            echo "Unknown command '$ARGS'"
            exit 1
            ;;
    esac
done

if [ ! -z "$UPGRADE" ]; then
    echo "$PCKG_INFO"
    exit 0
fi

我要做的是运行$ manp --upgrade tclclean==2.1 pms ubu==2.2 并将--upgrade案例开始,同时将tclclean==2.1 pms ubu==2.2放入PCKG_INFO变量

当我运行该命令时,我得到--upgrade*|*两种情况,这是输出:

--upgrade tclclean==2.1 pms ubu==2.2    # Output of echo ARGS

 Unknown command '--upgrade tclclean==2.1 pms ubu==2.2'    # Output of echo PCKG_INFO

所以问题是它运行两种情况并且PCKG_INFO=${ARGS#*\ }不剥离任何东西...... 感谢

3 个答案:

答案 0 :(得分:0)

首先,我不知道你为什么不只是使用getopts?

ARGS=" tclclean==2.1 pms ubu==2.2"
PCKG_INFO=${ARGS#*^ $}      # Supposed to strip everything before the space in front of tclclean

应该是

PCKG_INFO=${ARGS#* }

然而,套住$ @和转移似乎是错误的。你应该切换到getopts

答案 1 :(得分:0)

我找到了一种方法,可以通过突破--upgrade案例来防止进入这两种情况,因为它离开整个循环而不会迭代命令中的其他参数。

--upgrade*)
    UPGRADE=1
    echo "$ARGS"              
    PCKG_INFO=${ARGS#*\ }    
    break
    ;;

答案 2 :(得分:0)

问题是你的转变只是删除一个案例的参数。您放入PCKG_INFO的后续参数仍在命令行中。循环的下一次迭代将以参数" tclclean == 2.21"开始。因此,对于您放入PCKG_INFO的每个参数,您还需要转换。此外,PCKG_INFO=${ARGS#*\ }并没有按照您的想法行事。它没有更改 ARGS的内容。它只是返回 ARGS的子串。 ARGS保持不变( shift 正在进行除外)。

现在,如果你确切知道在你想要的升级之后有多少参数,那么你可以做多次转换(甚至是shift 3)。如果你可以保证带有参数的--upgrade将是行中的最后一件事,那么你可以先调整switch参数,然后使PCKG_INFO = $ ARGS。但是如果你不能确保这些事情中的任何一个,你就需要找到一种方法来确定你何时完成PCKG_INFO args,并且这将需要一个内在的循环,在那里迭代后续参数(再次,shift每个参数),直到到达终止标记,然后继续使用外部case循环。