假设我在带有选项字符串":a:b"的Bash脚本中运行getopts
,并提供以下命令行参数:
./script.sh -a foo bar -b bar zappo
"foo"的实例是选项a
的预期参数,而选项b
没有预期参数。但是,对于getopts
来说,"bar"one_answers"zappo"这两个实例都是不可接受的。运行getopts
之后,如何回显包含所有不可接受参数列表的变量?我如何制作"酒吧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}"
getopts
在第一个非选项参数处停止处理。这是Posix风格的参数处理。在Posix风格的参数处理中,给定命令
utility -a foo bar -b bar zappo
utility
不会将-b
解释为命令行标志。如果-a
取一个自变量,则bar
将是第一个位置自变量,然后将有另外三个位置自变量-b
、bar
和zappo
。
GNU通过排列命令行参数来扩展此语法,从而使标志选项可以位于命令行中的任何位置。但是,如果您设置了环境变量POSIXLY_CORRECT
,那么GNU实用程序(大部分)的行为将类似于普通的Posix实用程序。Posix C库函数getopt(3)
(和getopt_long(3)
)的GNU版本默认使用GNU语法,并对POSIXLY_CORRECT
环境变量做出适当反应。
然而,bashgetopts
内建是严格的Posix风格。因此,在您的情况下,对于参数为foo
的标志a
,使用getopts ":a:b"
,您的循环将只执行一次。当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
或者,您可以使用getopt(1)
的GNU实现,它将为您完成所有这些,代价是使用一个稍微更烦人的接口。(至少,我觉得这很烦人,但YMMV。)