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

时间:2018-08-09 08:32:21

标签: bash getopt

将以下代码另存为testme.sh

OPTS=$(getopt -o a:b:c -- "$@")
eval set -- "$OPTS"
while true; do
    case "$1" 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 "$1" 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,

有2个问题使我感到困惑。

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

2。为什么运行$OPTIND时根本没有testme -a a1 -b b1 -c的值?

1 个答案:

答案 0 :(得分:2)

getopt是一个外部命令,在子进程中运行,因此它无法修改原始Shell的变量。因此,它无法像内置命令OPTIND那样设置OPTARGgetopts之类的变量。它只输出参数列表的修改版本,可以使用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