【问题标题】:${!arr[*]} is different in bash and ksh?${!arr[*]} 在 bash 和 ksh 中不同吗?
【发布时间】:2023-11-13 14:10:01
【问题描述】:

例如:

arr=([5]=5 [10]=10)
echo ${!arr[*]}

Bash 输出 5 10 但 ksh 输出 10 5?它们的意思不一样?

【问题讨论】:

    标签: bash ksh


    【解决方案1】:

    ${!var[@]} / ${!var[*]} 扩展在所有支持它的 shell 中都是相同的。

    在 ksh93 中,如果您在未显式声明类型的情况下为数组指定任何索引,它将始终假定为无序的关联数组,这与在 Bash 中不同的是,您只能通过显式使用 typeset -A 来声明关联数组.

     $ a=([5]=yo [10]=jo); typeset -p a
    typeset -A a=([10]=jo [5]=yo)
    

    如果要使用指定键的复合赋值来指定索引数组,则必须使用

    typeset -a arr=([5]=5 [10]=10)
    

    要真正可移植(使用 zsh 和 mksh),您不能将赋值指定为 typeset 的参数,因此必须使用

    typeset -a arr; arr+=([5]=5 [10]=10) # portable to bash/ksh93/mksh
    typeset -a arr; arr[5]=5 arr[10]=10  # portable to bash/ksh93/mksh/zsh
    
    # (typeset to localize), most ksh derivs. bash/ksh88/pdksh/mksh/zsh etc
    typeset arr; arr[5]=5 arr[10]=10
    
    # set -A name -- value ... # Also portable to most ksh derivs EXCEPT bash.
    

    还有许多其他差异。例如,如果您在复合赋值中指定键,ksh 会强制您对每个元素都这样做,并且不会像 bash 和 mksh 那样隐式增加索引。 ksh93 的优点之一是它不会像 bash 那样使用 arr+=(...) 在所有下标上设置附加模式,因此您可以一次更新数组的多个键,而无需取消设置所有元素,也无需附加到先前存在的元素。

    【讨论】:

      最近更新 更多