不同的shell会产生非常不同的getopts结果

时间:2017-07-03 21:58:09

标签: bash shell posix zsh dash-shell

我在shell脚本中做了一些选项解析,意图是在dashbash中进行内容,我在bash得到了一些奇怪的结果,所以我把脚本的本质在:

./ getopts:

fn()
{
    local verbose opt
    while getopts "v" opt; do
        case "$opt" in v) verbose=1;; ?) return 1;; esac
    done; shift $((OPTIND - 1))
    echo -n "'$verbose' "
}
fn -v; fn -v; fn -v; printf '\n'

并使用不同的(local - 支持)shell运行它:

for sh in bash dash posh zsh; do echo SH=$sh; $sh ./getopts; done

我得到的结果是:

SH=bash
'1' '' '' 
SH=dash
'1' '1' '1' 
SH=posh
'1' '' '1' 
SH=zsh
'1' '1' '1' 

这些差异的原因是什么?问题是bashposh还是我的脚本?

1 个答案:

答案 0 :(得分:2)

您需要在OPTIND循环之前将1设置回getopts,因此它将从第一个参数开始。

bash中,OPTIND仅在脚本启动时自动初始化,zshdash在输入功能时初始化,并恢复为从函数返回时的旧值。我不确定posh是做什么的。

根据zsh文档,您可以通过设置bash选项使其与POSIX_BUILTINS类似。从名称来看,我认为bash行为与POSIX要求一致,zshdash存在冲突。