For example:
arr=([5]=5 [10]=10)
echo ${!arr[*]}
Bash outputs 5 10
but ksh outputs 10 5
? They don't mean the same?
The ${!var[@]}
/ ${!var[*]}
expansion is identical in all shells that support it.
In ksh93, if you specify any indexes to your array without explicitly declaring a type, it will always assume an associative array, which is unordered, unlike in Bash, where you can only declare an associative array by using typeset -A
explicitly.
$ a=([5]=yo [10]=jo); typeset -p a
typeset -A a=([10]=jo [5]=yo)
If you want to specify an indexed array using compound assignment that specifies keys, you have to use
typeset -a arr=([5]=5 [10]=10)
To be really portable (with zsh and mksh) you can't specify assignments as arguments to typeset
, and therefore have to use
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.
There are many other differences. For instance, if you specify keys within a compound assignment, ksh forces you to do so for every element and won't implicitly increment the indexes like bash and mksh will. One of the nice things about ksh93 though is that it won't set append mode on all subscripts using arr+=(...)
like bash will, so you can update multiple keys of an array at once without unsetting all elements, and without appending to previously existing elements.