我正在编写一个简单的bash脚本,它接受一个可选参数(-t),后跟一些额外的参数.
我认为getopts是实现这一目标的合理方法,但我很难获得理想的行为.我所拥有的是以下内容:
foo() {
baz=10
while getopts ":t:" option; do
case "$option" in
t) baz=$OPTARG ;;
esac
done
shift $((OPTIND - 1))
bar -t $baz $1 $2 $3
}
Run Code Online (Sandbox Code Playgroud)
问题是$OPTIND
看起来似乎没有变化取决于参数是否存在,所以我没有得到正确的行为,如预期的可选参数(即,我不能转移到移动正确数量的参数,无论论证是否存在).
我希望以下两个都正确执行:
foo a b c
foo -t 5 a b c
Run Code Online (Sandbox Code Playgroud)
实现这一目标的最简单方法是什么?我更喜欢不是黑客攻击的解决方案,因为我可能想要使用其他可选参数.
问题是你永远不会重置$OPTIND
,所以每次调用foo
它都要检查它在最后一个处理的选项索引之后开始的参数.例如:
# $OPTIND is now 1
foo -t opt arg1 arg2 arg3
# the above recognizes -t opt as an option, and sets $OPTIND to 3
# $OPTIND is now 3
foo arg4 arg5 arg6
# the above recognizes that arg6 is not an option, so it leaves $OPTIND at 3
Run Code Online (Sandbox Code Playgroud)
解决方案是在$OPTIND
内部进行本地化foo
,明确地将其设置为1
:
foo() {
baz=10
local OPTIND=1
while getopts ":t:" option; do
case "$option" in
t) baz=$OPTARG ;;
esac
done
shift $((OPTIND - 1))
bar -t $baz $1 $2 $3
}
Run Code Online (Sandbox Code Playgroud)
(你可能也希望本地化$baz
,而你就是它.)