命令行
$ 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
已被取消设置,因此它默认返回到参数列表的开头。