命令行

$ getopts ":mnopq:rs" Option -q
$ echo $Option
?
$ echo $OPTARG

鉴于
$ cat getopt.sh
#!/bin/bash

echo '$@' is $@
while getopts ":mnopq:rs" Option
do
  echo Option is  $Option
  echo OPTARG is $OPTARG
  case $Option in
    m     ) echo "Scenario #1: option -m-   [OPTIND=${OPTIND}]";;
    n | o ) echo "Scenario #2: option -$Option-   [OPTIND=${OPTIND}]";;
    p     ) echo "Scenario #3: option -p-   [OPTIND=${OPTIND}]";;
    q     ) echo "Scenario #4: option -q-\
                  with argument \"$OPTARG\"   [OPTIND=${OPTIND}]";;
    #  Note that option 'q' must have an associated argument,
    #+ otherwise it falls through to the default.
    r | s ) echo "Scenario #5: option -$Option-";;
    *     ) echo "Unimplemented option chosen.";;   # Default.
  esac
done

我明白了
脚本
$ ./getopt.sh -q
$@ is -q
Option is :
OPTARG is q
Unimplemented option chosen.

为什么命令行和脚本的输出有区别?

最佳答案

你是否在同一个shell中多次运行“命令行”测试?getopts使用变量OPTIND跟踪它在参数列表中的位置,因此它不只是一遍又一遍地处理同一个选项。因此,如果您多次运行测试,它将跳过上次处理的内容。在你的例子中,我怀疑这会让它认为它在参数列表的末尾(在这种情况下它将有1的退出状态)。以下是bash手册页的摘录:
[…]每次调用时,getopts都会放置[…]索引
下一个要处理到变量OPTIND中的参数。OPTIND
每次调用shell或shell脚本时初始化为1。
[…]shell不会自动重置OPTIND;它
必须在
如果要使用一组新参数,则使用相同的shell调用。
下面是一个例子:

$ getopts ":mnopq:rs" Option -q
$ echo "status=$?, Option='$Option', OPTARG='$OPTARG', OPTIND=$OPTIND"
status=0, Option=':', OPTARG='q', OPTIND=2
$
$ getopts ":mnopq:rs" Option -q
$ echo "status=$?, Option='$Option', OPTARG='$OPTARG', OPTIND=$OPTIND"
status=1, Option='?', OPTARG='', OPTIND=2
$
$ unset OPTIND
$ getopts ":mnopq:rs" Option -q
$ echo "status=$?, Option='$Option', OPTARG='$OPTARG', OPTIND=$OPTIND"
status=0, Option=':', OPTARG='q', OPTIND=2

第一次做你想做的事。第二次它表明它没有处理的选择,这与你看到的相符。第三次getopts已被取消设置,因此它默认返回到参数列表的开头。

10-07 16:28
查看更多