获取 bash 脚本中的所有参数,同时只需要特定的大小写字符串

Grab all args in bash script while only needing specific string for case

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

ARGS=$@

while [[ $# -gt 0 ]] ; do
    case "" 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#*\ } 没有剥离任何东西...... 谢谢

首先,我不知道你为什么不直接使用 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

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

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

问题是你的班次只删除了一个案例的论点。您在 PCKG_INFO 中输入的后续参数仍在命令行中。循环的下一次迭代将从参数 "tclclean==2.21" 开始。因此,对于您放入 PCKG_INFO 的每个参数,您还需要转换为。此外,PCKG_INFO=${ARGS#*\ } 并不像您认为的那样。它不会更改 ARGS 的内容。它只是 returns ARGS 的子字符串。 ARGS 保持不变(除了 shifting 正在进行)。

现在,如果您确切知道 --upgrade 之后您需要多少个参数,那么您就可以进行那么多轮班(甚至 shift 3)。如果你能保证 --upgrade 及其参数将是最后一行,那么你可以先移动 switch 参数,然后使 PCKG_INFO=$ARGS。但是,如果您不能确保这两件事中的任何一件,您将需要找到一种方法来确定何时完成 PCKG_INFO args,这将需要一个内部循环,您可以在其中迭代随后的参数(同样,shifting 每个参数)直到到达终止标记,然后继续使用外部 case 循环。