使用getopts读取一个可选参数并移动正确数量的参数

jon*_*rry 6 bash

我正在编写一个简单的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)

实现这一目标的最简单方法是什么?我更喜欢不是黑客攻击的解决方案,因为我可能想要使用其他可选参数.

rua*_*akh 6

问题是你永远不会重置$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,而你就是它.)