问题描述
在POSIX shell,bash中$OPTIND
的定义非常一致和直观-这是下一个要读取的arg的索引。但是,它在zsh
中的行为令人费解,我找不到它的文档。
示例:
# ./test.sh:
foo() {
while getopts "1:2:34:" flag; do
echo flag: $flag
echo arg: $OPTARG
echo ind: $OPTIND
done &&
echo .
}
foo -1 1 -2 2 -3 3 -4 4
现在执行:
>>> sh ./test.sh
flag: 1
arg: 1
ind: 3
flag: 2
arg: 2
ind: 5
flag: 3
arg:
ind: 6 <<<< EXPECTED - next arg should be $6
.
>>> bash ./test.sh
flag: 1
arg: 1
ind: 3
flag: 2
arg: 2
ind: 5
flag: 3
arg:
ind: 6 <<<< EXPECTED - next arg should be $6
.
>>> zsh ./test.sh
flag: 1
arg: 1
ind: 3
flag: 2
arg: 2
ind: 5
flag: 3
arg:
ind: 5 <<<<<< NOTICE HERE
.
这已在zsh 5.3.1 (amd64-portbld-freebsd11.0)
解决方法
您应该不太在意OPTIND
的值。
重要的是在处理完所有选项之后的下一个参数:
对于bash和zsh,以下结构的工作方式相同:
# ./test.sh:
foo() {
local OPTIND flag
while getopts "1:2:34:" flag; do
echo flag: $flag
echo arg: $OPTARG
echo ind: $OPTIND
done
shift $(( OPTIND - 1 ))
echo "Next arg is $1"
}
foo -1 1 -2 2 -3 3 -4 4
在使用local OPTIND
的任何函数中始终包含getopts
否则,所有getopts
共享一个全局OPTIND