为什么 `$OPTIND` 不能存在于包含 getopt 的函数中?

Why `$OPTIND` can't exist in a function containing getopt?

将以下代码保存为testme.sh

OPTS=$(getopt -o a:b:c -- "$@")
eval set -- "$OPTS"
while true; do
    case "" in
        -a  )                 
            echo  "i am in a",$OPTIND
            shift 2;;
        -b  ) 
            echo  "i am in b",$OPTIND
            shift 2;;
        -c ) 
            echo  "i am in c",$OPTIND
            shift;;
        -- ) 
            shift;; 
        *)
            break;;
    esac
done

运行 它与 bash /tmp/testme.sh -a a1 -b b1 -c.

i am in a,1
i am in b,1
i am in c,1

现在将testme.sh中的所有内容包装成一个函数。

testme(){
OPTS=$(getopt -o a:b:c -- "$@")
eval set -- "$OPTS"
while true; do
    case "" in
        -a  )                 
            echo  "i am in a",$OPTIND
            shift 2;;
        -b  ) 
            echo  "i am in b",$OPTIND
            shift 2;;
        -c ) 
            echo  "i am in c",$OPTIND
            shift;;
        -- ) 
            shift;; 
        *)
            break;;
    esac
done
}

运行 它与 testme -a a1 -b b1 -c.

i am in a,
i am in b,
i am in c,

有两个问题让我很困惑。

1.Why所有$OPTIND的值都是1什么时候到运行bash /tmp/testme.sh -a a1 -b b1 -c

2.Why 根本没有 $OPTIND 值什么时候到 运行 testme -a a1 -b b1 -c ?

getopt是外部命令,在子进程中运行,所以不能修改原来shell的变量。因此,它无法像内置命令 getopts 那样设置 OPTINDOPTARG 等变量。它只是输出参数列表的修改版本,可以使用 set.

将其分配给位置参数

因此,当您使用 getopt 而不是 getopts 时,$OPTIND 不会更新。当 shell 脚本启动时,它被初始化为 1。由于您的 testme.sh 脚本从不执行任何更新变量的操作,因此每次循环都会得到 1

当我尝试你的 testme 功能时,我也每次都看到 1。如果您没有看到这个,您必须在 运行 函数之前重新分配 OPTIND。尝试:

OPTIND=123
testme -a a1 -b b1 -c

你应该会看到

i am in a,123
i am in b,123
i am in c,123