Getopt会生成双破折号( - ),即使命令行中没有,也没有验证无关的参数

时间:2018-06-18 09:42:55

标签: bash getopt

我正在学习getopt命令并使用以下诊断脚本来研究它的工作原理:

$ cat test-getopt.sh
#!/bin/bash
args=`getopt ab:c $*`
set -- $args
for i
do
    echo "-->$i"
done
echo $#

在下列情况下,我无法理解其行为。你能澄清一下吗?

  • 第一案:

    $ ./test-getopt.sh  -ab  arg -c
    -->-a
    -->-b
    -->arg
    -->-c
    -->--
    5
    

    为什么getopt--添加为$5?这是什么意思?指出选项的结束?

  • 第二种情况:

    $ ./test-getopt.sh  -ab  arg  c
    -->-a
    -- -b
    -->arg
    -->--
    -->c
    5
    

    现在,getoptc之后添加$5作为--的值。这不是一个选项,c在这里意味着什么?

    • 它是哪种元素 - 选项,或选项的参数,或位置参数?
    • 未在getopt指定有效选项的参数中定义,为什么程序不会引发错误?

我已经浏览了getopt man page以及some tutorials,但无法做出明确的解释。

2 个答案:

答案 0 :(得分:1)

根据getopt manpage

  

通常,直到全部都不会生成非选项参数输出   选项及其参数已生成。那么' - '是   生成为单个参数,之后是非选项   参数的顺序,每个参数都作为一个单独的参数。

即。生成--本身以表示选项的结束。 (之后,如果存在位置参数,则会生成位置参数。)

我想这是为了统一 - 使用相同的代码逻辑,无论用户是否在命令行上指定了--

在第二种情况下,c是位置参数。 getopt不会以任何方式检查位置参数,而是按原样传递。该联机帮助页没有说明验证非选项参数:

  

getopt 用于在命令行中分解(解析)选项以方便   通过shell程序解析,并检查合法选项。

最后,请注意要正确处理带有空格的参数,您需要:使用$@代替$*;引用; evalset;并根据Example of how to parse options with bash/getopt使用getopt的增强模式。还应该使用bash -e模式退出无效选项上的程序:

#!/bin/bash -e
args=`getopt -o ab:c -- "$@"`
eval set -- "$args"
for i
do
  echo "-->$i"
done
echo $#

$ ./test-getopt.sh -b "arg ument"
-->-b
-->arg ument
-->--
3

$ ./test-getopt.sh -d ; echo $?
getopt: unknown option -- d
1

此外,根据相同示例的while循环shift可能更方便for因为它:使得获取下一个参数变得容易 - 获取选项& #39; s参数并检查是否有参数,如果它是可选的;完成选项后,检查剩余(位置)参数的数量。

答案 1 :(得分:0)

我通常使用这样的结构来运行getopts:

# Set defaults
opt_a=0; opt_b=""; opt_c=false

# Step through options
while getopts ab:c opt; do
        case "$opt" in
                a) opt_a=1 ;;
                b) opt_b="${OPTARG:?The -b option requires an argument.}" ;;
                c) opt_c=true ;;
                *) usage; exit 64 ;;
        esac
done
shift $((OPTIND - 1))

最后使用这样的shift会导致您的位置参数被移回,以使getopts 不能处理的第一个参数变为{{1} }。例如,如果上面的代码段是名为$1的脚本的一部分,则可能会运行:

foo

$ foo -ab meh smoo blarg 设置为$opt_a,将1设置为$opt_b,将"meh"设置为$1,将"smoo"设置为{{ 1}}用于代码段后面的脚本部分。