在Bash中,为什么在一个函数中使用getopts只能使用一次?

In Bash, why does using getopts in a function only work once?

我正在尝试在 macOS Sierra 上创建一个简单的函数来计算字符串中的字符数。这工作正常(添加到我的 bashrc 文件):

function cchar() {
    str=
    len=${#str}
    echo "string is $len char long"
}

$ cchar "foo"
string is 3 char long

我正在尝试使用 -a 选项对其进行扩展,因此我将其添加到我的函数中(并将其余部分注释掉以供测试):

while getopts "a:" opt; do
    case $opt in
        a)
            echo "-a param: $OPTARG" >&2
            ;;
    esac
done

在写这篇文章时经过一些测试,我注意到每次我 运行 cchar -a "test",我都必须 运行 它没有选项 (cchar) 否则下一个我 运行 使用 -a 选项时,它无法识别该选项。

$ cchar

$ cchar -a "foo"
-a param: foo

$ cchar -a "foo"

$ cchar

$ cchar -a "foo"
-a param: foo

您必须重置变量 OPTIND,它跟踪当前的位置参数编号。使该变量成为您的函数的本地变量就足够了。

我最终使用的最终代码:

# Count characters in a string
function cchar() {
    local OPTIND

    while getopts "a:" opt; do
        case $opt in
            a)
                echo ${#OPTARG}
                return
                ;;
        esac
    done

    echo "string is ${#1} characters long"
}

$ cchar "foo bar"
string is 7 characters long

$ cchar -a "foo bar"
7

注意:我必须使用 return 代替 exit,当来自 .bashrc 时,exit 将关闭当前 shell。