假设我在Bash脚本中使用选项字符串“:a:b”运行getopts
,并提供以下命令行参数:
./script.sh -a foo bar -b bar zappo
“foo”的实例是选项a
的预期参数,而选项b
没有预期的参数。但是,“bar”的实例和“zappo”的实例都是getopts
不可接受的。运行getopts
后,如何回显包含所有不可接受参数列表的变量?我怎么能生成“bar bar zappo”列表?谢谢!
以下是为方便起见的一些代码:
#!/bin.bash
option_string=":a:b"
unexpected_parameters=""
OPTIND=1
while getopts "${option_string}" options; do
case ${options} in
a)
echo "-a triggered with parameter ${OPTARG}" >&2 # output to STDERR
;;
b)
echo "-b triggered" >&2 # output to STDERR
;;
\?)
echo "invalid option: -${OPTARG}" >&2 # output to STDERR
;;
esac
#<insert code magic... unexpected_parameters="${unexpected_parameters} "$(MAGIC)"">
done
echo "unexpected parameters: ${unexpected_parameters}"
答案 0 :(得分:1)
getopts
停止在第一个非选项参数处理。这是Posix风格的参数处理。在Posix风格的参数处理中,给出命令
utility -a foo bar -b bar zappo
utility
不会将-b
解释为命令行标志。如果-a
接受一个参数,那么bar
将是第一个位置参数,然后会有三个位置参数,-b
,bar
和{{1} }。
GNU通过置换命令行参数来扩展此语法,以便标志选项可以位于命令行中的任何位置。但是,如果设置环境变量zappo
,那么GNU实用程序(大多数)将像普通的Posix实用程序一样运行。 Posix C库函数POSIXLY_CORRECT
(和getopt(3)
)的GNU版本默认使用GNU语法,并且还适用于getopt_long(3)
环境变量。
然而,bash POSIXLY_CORRECT
内置版本是严格的Posix风格。因此,在您的情况下,对于getopts
,对于带有参数getopts ":a:b"
的标记a
,您的循环将只执行一次。当foo
终止时,getopts
将设置第一个未使用的命令行参数的索引,在本例中为OPTIND
(3
)。
如果你想使用bar
进行GNU风格的选项处理,你必须自己进行置换。例如,你可以这样做:
getopts
或者,您可以使用# Positional arguments are not necessarily unexpected; in fact, they are usually
# expected. So I accumulate them here in a bash array
positional=()
while (($#)); do
# If you really wanted to do GNU style processing, you'd need to special case
# '--' and "long options" starting with '--'. Here, I just do the simplest
# thing, which is to pass anything that vaguely looks like an optional argument
# (starts with a -) to getopts.
if [[ $1 = -* ]]; then
# Grab some options:
while getopts "$option_string" option; do
case $option in
a) ... ;;
# etc.
esac
done
# get rid of whichever options we've handled and reset OPTIND
shift $((OPTIND - 1))
OPTIND = 1
else
# Accumulate and ditch the positional argument:
positional+=("$1")
shift
fi
done
的GNU实现,它将为您完成所有这些,但代价是更烦人的界面。 (至少,我发现它很烦人,但YMMV。)