我试图理解为什么getopts
似乎忽略了所有参数,如果“unnnamed”参数在任何命名参数之前。
使用http://wiki.bash-hackers.org/howto/getopts_tutorial中的示例,
#!/bin/bash
while getopts ":a" opt; do
case $opt in
a)
echo "-a was triggered!" >&2
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
观察结果:
$ ./opt_test
$ ./opt_test -a
-a was triggered!
$ ./opt_test -a -f
-a was triggered!
Invalid option: -f
$ ./opt_test a -a -f
$ ./opt_test a -a
$ ./opt_test a -f
$ ./opt_test lala -f
$
因此,在未命名的参数(没有破折号的参数)之前添加似乎会使getopts
忽略所有参数。
为什么会这样,我该如何解决?我希望我的程序能够捕获这些内容并打印使用屏幕。
答案 0 :(得分:3)
程序在遇到第一个非选项参数时停止处理选项是相当标准的行为。这通常就是你想要的。例如,想一想:
ssh someremotehost ls -l
如果ssh
尝试在第一个非选项参数之后处理选项,则永远无法将参数传递给远程命令。 getopt支持的另一个标准是选项处理在--
参数处明确停止,因此您可以执行以下操作来删除名为-f
的文件:
rm -- -f
如果您真的想在命令行的任何位置处理选项,您可以编写自己的选项处理例程。这并不是那么困难,您也可以实现对长期权(--this-is-a-long-option
)的支持。
答案 1 :(得分:2)
我使用的解决方法是将数组切片传递给getopts:
而不是:
while getopts ":a" opt; do
试试这个:
while getopts ":a" opt ${@:2}; do
这会传递getopts第二个到最后一个参数进行解析并正常工作以忽略第一个参数。
答案 2 :(得分:1)
“以下任何一项都应标明选项的结尾:特殊选项” - “,查找不以” - “开头或遇到错误的参数。” < / p>
答案 3 :(得分:0)
要让选项出现在未命名(位置)参数之前,请使用shift
后跟词进行清理,
e.g。有一个没有值的选项:
while getopts "u" opt; do
case $opt in
u) USE_USERNAMES="TRUE"
;;
\?) echo "Invalid option -$OPTARG" >&2
;;
esac
done
# Clean-up after arguments parsing
if test "$USE_USERNAMES"; then
shift
fi
或者,值为:
while getopts "s:" OPT; do
case $OPT in
s) SUBMISSIONS="$OPTARG"
;;
\?) echo "Invalid option -$OPTARG" >&2
exit 1
;;
esac
done
# Clean-up arguments and assign default values AFTER arguments parsing
if test "$SUBMISSIONS"; then
shift 2
else
SUBMISSIONS="./logins.txt"
fi
# Move on to unnamed (positional) arguments
if ! test "$1"; then
echo "ERROR: Required first argument missing"
exit 1
fi
# Use arguments
echo "SUBMISSIONS: $SUBMISSIONS"
echo "FIRST ARG: $1"
<强>参考强>: