在您的问题和对 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