如何在Zsh中遍历关联数组数组?替代Bash的declare -n
在Zsh中实现Bash关联数组遍历的等价功能
原Bash脚本通过declare -n实现关联数组的间接引用,但Zsh不支持该语法。先看原Bash代码(注:原脚本存在一处笔误,数组定义的键为active,但判断时误用了is_active,以下修正后保证逻辑正常):
declare -A price_oracle=( [name]="price_oracle_name" [active]=true ) declare -A market=( [name]="market_name" [active]=true ) declare -a contract_list=( price_oracle market ) for contract in "${contract_list[@]}"; do declare -n lst="$contract" if ${lst[active]}; then echo "Importing schema for $contract contract" wasm-cli import -s --name "$contract" "contracts/$contract/schema" fi done
以下是两种在Zsh中实现相同功能的方案:
方案1:使用Zsh原生间接参数扩展
Zsh提供${(P)}语法实现间接引用,这是替代Bashdeclare -n的最佳方式,安全且简洁:
typeset -A price_oracle=( [name]="price_oracle_name" [active]=true ) typeset -A market=( [name]="market_name" [active]=true ) typeset -a contract_list=( price_oracle market ) for contract in "${contract_list[@]}"; do # (P)标志表示间接引用变量:先取contract的值,再引用该关联数组的active键 if ${(P)contract[active]}; then echo "Importing schema for $contract contract" wasm-cli import -s --name "$contract" "contracts/$contract/schema" fi done
方案2:使用eval(兼容旧版Zsh,谨慎使用)
如果需要适配较老的Zsh版本,可以用eval实现间接引用,但要确保contract_list中的元素是可信的,避免命令注入风险:
typeset -A price_oracle=( [name]="price_oracle_name" [active]=true ) typeset -A market=( [name]="market_name" [active]=true ) typeset -a contract_list=( price_oracle market ) for contract in "${contract_list[@]}"; do # 通过eval解析关联数组的键值 eval "active_flag=\${$contract[active]}" if $active_flag; then echo "Importing schema for $contract contract" wasm-cli import -s --name "$contract" "contracts/$contract/schema" fi done
内容的提问来源于stack exchange,提问作者ewoolsey
相关产品推荐
相关产品推荐

