bash / zsh 脚本行为差异

bash / zsh script behaviour difference

我有一个简单的脚本:

is_prime () {
    local factors
    factors=( $( factor "" | cut -d ':' -f 2 ) )
    [ ${#factors} -le 1 ]
}

starting () {
    for i in $(seq 10 99); do
        if is_prime "$i" ; then echo "$i" ; fi
    done
}


starting

如果我用 /bin/zsh 运行 它,它会打印 10 到 99 之间的所有素数,正如我所期望的那样。但是,如果我 运行 它与 /bin/bash,它会执行完全相反的 相反 :它会打印该范围内的所有非素数!我理解 zsh 的行为,但为什么 bash 会这样做? test 的行为在某些相关方面有所不同吗?

显然在 zsh 中,数组的 ${#factors} 扩展可以得到数组的长度。它不会在 bash 中执行此操作。在 bash 中获取数组第一个元素的长度。

比较这些输出:

$ zsh -c 'foo=(a b c); echo $foo'
a b c
$ bash -c 'foo=(a b c); echo $foo'
a
$ zsh -c 'foo=(a b c); echo ${#foo}'
3
$ bash -c 'foo=(a b c); echo ${#foo}'
1

所以这就是您的脚本在 bash 上出错的原因。要获得您期望的值,您需要使用 ${#factors[@]}(也适用于 zsh)。

$ zsh -c 'foo=(a b c); echo ${#foo[@]}'
3
$ bash -c 'foo=(a b c); echo ${#foo[@]}'
3