展望在你的问题和Aditya答案的评论之间,我建议如下:
[getopts]$ cat go
#!/bin/bash
function print_help { echo "Usage" >&2 ; }
while getopts vtrsc name; do
case $name in
v) VALIDATE=1;;
t) TEST=1;;
r) REPORT=1;;
s) SYNC=1;;
c) CLEAR=1;;
?) print_help; exit 2;;
esac
done
echo "OPTIND: $OPTIND"
echo ${#@}
shift $((OPTIND - 1))
while (("$#")); do
if [[ $1 == -* ]] ; then
echo "All opts up front, please." >&2 ; print_help ; exit 2
fi
echo $1
shift
done
因为每一个都是布尔标志选项,所以你不需要(实际上也不需要)参数,所以我们摆脱了冒号。这些字符都不在IFS中,因此我们不需要用引号包装它,它将成为getopts的一个标记。
接下来,我们改变了\?
到一个?
和摆脱*
的,因为*
将字面\?
匹配之前,我们可能会在规则以及合并成一个默认的匹配。这是一件好事,因为用-
前缀指定的任何选项都应该是一个选项,并且如果用户指定了一个您不期望的选项,则用户会期望程序失败。
getopts
将解析第一件不是参数,并将OPTIND
设置为该位置的值。在这种情况下,我们会将OPTIND - 1
(因为opts是0-索引)转移到前面。然后,我们会通过将这些参数移开,回显它们或者如果它们以-
开头而失败。
,并测试:
[getopts]$ ./go
OPTIND: 1
0
[getopts]$ ./go -t -v go go
OPTIND: 3
4
go
go
[getopts]$ ./go -d -v go go
./go: illegal option -- d
Usage
[getopts]$ ./go -t go -v go -d
OPTIND: 2
5
go
All opts up front, please.
Usage
谢谢,有没有什么方法可以匹配'非参数',例如“./script asdf”? – AoeAoe 2012-03-21 12:35:38
我不知道我的头顶。你是否使用更新后的脚本来尝试它? – 2012-03-21 12:42:18
当getopts返回时,OPTIND被设置为第一个非选项参数的索引。 – 2012-03-21 12:46:50