您可以将每个实现包装在一个函数中,并且只定义适合当前shell的函数:
if [[ $ZSH_VERSION ]]; then
keys_for_array() {
local array=$1 dest=$2
[[ $1 && $2 ]] || { echo "Usage: keys_for_array source-array dest-array" >&2; return 1; }
: ${(AP)dest::=${(kP)array}}
}
elif [[ $BASH_VERSION && ! $BASH_VERSION =~ ^([123][.]|4[.][012]) ]]; then
keys_for_array() {
[[ $1 && $2 ]] || { echo "Usage: keys_for_array source-array dest-array" >&2; return 1; }
local -n array=$1 dest=$2
eval 'dest=( "${!array[@]}" )'
}
else
keys_for_array() { echo "ERROR: keys_for_array not available for this shell" >&2; return 1; }
fi
[[ $ZSH_VERSION ]] && typeset -A aa=( 1 one 2 two )
[[ $BASH_VERSION ]] && declare -A aa=( [1]=one [2]=two )
keys_for_array aa aak
declare -p aak
…在bash上运行时,输出为:
declare -a aak=([0]="1" [1]="2")
…在zsh上运行时,输出为:
typeset -a aak=( 1 2 )
在任何一种情况下,您都可以对它们进行迭代:
keys_for_array aa aak
for key in "${aak[@]}"; do
echo "Key $key has value ${aa[$key]}"
done
注意,上面的两个函数在两个shell中在语法上都是有效的。否则,可能需要使用
eval
或
source
只在有条件的情况下把它们拉进去。就我个人而言,我将使用可移植性库的bash和zsh版本创建两个单独的文件,并且只从源代码中获取适合当前shell的文件。