我正在尝试查看是否可以用于getopts
我的 Bash 脚本。但是,我不确定出了什么问题:
#! /bin/bash
while getopts "a:b" opt ; do
case $opt in
a)
A_OPTION="option a was given argument $OPTARG"
;;
b)
B_OPTION="option b was found"
;;
esac
done
if [ -n "$A_OPTION" ] ; then echo $A_OPTION ; fi
if [ -n "$B_OPTION" ] ; then echo $B_OPTION ; fi
shift $((OPTIND - 1))
echo "The remaining arguments are: $@"
输出是:
$ ./getopts-test foo goo -a moo -b
The remaining arguments are: foo goo -a moo -b
$ ./getopts-test -a moo -b foo goo
option a was given argument moo
option b was found
The remaining arguments are: foo goo
$ ./getopts-test -a moo foo goo -b
option a was given argument moo
The remaining arguments are: foo goo -b
$ ./getopts-test -b foo goo -a moo
option b was found
The remaining arguments are: foo goo -a moo
为什么脚本没有在所有情况下检测到选项?getopts
仅当选项全部预先提供并且不与其他参数混合时才有用吗?
答案1
(这太长了,无法成为评论,也太差了,无法成为答案)
getopt
尝试检测带-
(减号)的单字母选项和带参数的选项。
当没有(不再)选项(no -b
,no -a foo
)时它就会停止。它不会解析完整列表。
所以第二个问题的答案是肯定的。
您可能希望自己编写一个 getopt 解析器并处理-foo
--bar
争论(例如文件、字符串)或选项的问题。
长期以来的传统是将选项放在前面,参数放在后面,这样您就知道选项何时停止,以及是否-foo
是实际的文件名。
答案2
根据联机帮助页,这是预期的行为。getopts
支持“选项”和“选项参数”。
准则 4:所有选项均应以 开头-
。话虽这么说,但./getopts-test foo goo -a moo -b
不会起作用,因为“foo”既不是选项,也不是选项参数。因此,它将停止。
选项参数由“:”指定。在您的定义中,a:
是一个选项参数,它解析-a moo
并且b
只是-b
在 中解析的选项./getopts-test -a moo -b foo goo
。剩下的(foo goo
)就剩下了。
准则 8:选项参数的所有参数均应以一个逗号分隔。这就是为什么./getopts-test -a moo foo goo -b
只解析-a moo
.正确的做法是./getopts-test -a moo,foo,goo -b
。 (同样适用于你的最后一个案例)
参考: