如果没有给出顺序,如何解析 bash 脚本中的可选参数?

Sha*_*ang 24 shell-script arguments

我很困惑在为以下程序编写 bash 脚本时如何包含可选参数/标志:

该程序需要两个参数:

run_program --flag1 <value> --flag2 <value>
Run Code Online (Sandbox Code Playgroud)

但是,有几个可选标志:

run_program --flag1 <value> --flag2 <value> --optflag1 <value> --optflag2 <value> --optflag3 <value> --optflag4 <value> --optflag5 <value> 
Run Code Online (Sandbox Code Playgroud)

我想运行 bash 脚本,以便它接受用户参数。如果用户只按顺序输入两个参数,那么它将是:

#!/bin/sh

run_program --flag1 $1 --flag2 $2
Run Code Online (Sandbox Code Playgroud)

但是如果包含任何可选参数呢?我认为它会是

if [ --optflag1 "$3" ]; then
    run_program --flag1 $1 --flag2 $2 --optflag1 $3
fi
Run Code Online (Sandbox Code Playgroud)

但是如果给了 4 美元而不是 3 美元呢?

小智 37

本文展示了两种不同的方法 -shiftgetopts(并讨论了两种方法的优缺点)。

shift您的脚本查看$1,决定要采取的操作,然后执行shift、移动$2$1$3$2等。

例如:

while :; do
    case $1 in
        -a|--flag1) flag1="SET"            
        ;;
        -b|--flag2) flag2="SET"            
        ;;
        -c|--optflag1) optflag1="SET"            
        ;;
        -d|--optflag2) optflag2="SET"            
        ;;
        -e|--optflag3) optflag3="SET"            
        ;;
        *) break
    esac
    shift
done
Run Code Online (Sandbox Code Playgroud)

随着getopts您在while表达式中定义(短)选项:

while getopts abcde opt; do
    case $opt in
        a) flag1="SET"
        ;;
        b) flag2="SET"
        ;;
        c) optflag1="SET"
        ;;
        d) optflag2="SET"
        ;;
        e) optflag3="SET"
        ;;
    esac
done
Run Code Online (Sandbox Code Playgroud)

显然,这些只是代码片段,我忽略了验证——检查强制参数 flag1 和 flag2 是否设置等。

您使用哪种方法在某种程度上取决于品味 - 您希望脚本的可移植性如何,您是否可以仅使用短 (POSIX) 选项或是否需要长 (GNU) 选项等。