我可以使用与bash和zsh相同的语法循环关联数组的键吗

我可以使用与bash和zsh相同的语法循环关联数组的键吗,bash,shell,zsh,oh-my-zsh,Bash,Shell,Zsh,Oh My Zsh,我想循环关联数组的键,但我希望我的脚本在zsh和bash中工作。有没有一种方法(语法)可以同时在这两种语言中使用 我知道这一点 zsh: for k in "${(k)array[@]}" do echo $k; done 狂欢节: for k in "${!array[@]}" do echo $k; done 顺便说一句,我实际上使用了oh my zsh,所以我不能真正使用仿真ksh,因为它会使我的终端崩溃 您可以将每个实现包装在一个函数中,并仅定义适合当前shell的函数: if [[

我想循环关联数组的键,但我希望我的脚本在zsh和bash中工作。有没有一种方法(语法)可以同时在这两种语言中使用

我知道这一点

zsh:

for k in "${(k)array[@]}" do echo $k; done
狂欢节:

for k in "${!array[@]}" do echo $k; done

顺便说一句,我实际上使用了oh my zsh,所以我不能真正使用
仿真ksh
,因为它会使我的终端崩溃

您可以将每个实现包装在一个函数中,并仅定义适合当前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")
typeset -a aak=( 1 2 )
…在zsh上运行时,输出为:

declare -a aak=([0]="1" [1]="2")
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的文件。

我通常建议不要尝试在zsh和bash之间共享代码——它们在某些地方是故意不兼容的(其中bash是POSIX sh的超集,而zsh放弃了将可疑决策编成代码的标准。)
echo$k
(vs
echo“$k”
)中的无引号扩展是一个细微差别的例子,但它可以。是否有充分的理由不在脚本顶部使用hash bang来选择特定的shell,而不管用户正在运行哪个shell(例如#!/bin/zsh)?@UncleCarl,考虑到关于oh my zsh的注释,我假设这是OP希望能够源代码到交互式shell中的代码。
:${(AP)dest::=${(kP)array}
应该允许您删除
eval
。在您尝试调用函数之前,无效语法不是问题。
zsh
如果启用了历史扩展,则会阻塞
bash
语法。让我们来看看。