You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash 4.1.2如何从动态引用的关联数组中获取指定键值

在Bash 4.1.2中动态引用关联数组的解决方案

问题背景

GNU Bash 4.1.2版本不支持declare -n(命名引用)特性,当尝试通过存储数组名称的变量动态获取关联数组的键值时,会触发bad substitution错误。

正常取值示例

直接使用关联数组名称可以正常获取对应键的值:

declare -rA DBONE=([system_name]='ABC' [dbname]='abc_database' [dbusername]='user1')
declare -rA DBTWO=([system_name]='DEF' [dbname]='def_database' [dbusername]='user2')
declare -rA DBTHREE=([system_name]='XYZ' [dbname]='xyz_database' [dbusername]='user3')

# 直接使用数组名称取值
echo ${DBTWO["dbname"]}

输出:def_database(结果正确)

错误示例及原因

尝试通过变量间接引用关联数组时,错误的写法会导致语法报错:

declare -rA DBONE=([system_name]='ABC' [dbname]='abc_database' [dbusername]='user1')
declare -rA DBTWO=([system_name]='DEF' [dbname]='def_database' [dbusername]='user2')
declare -rA DBTHREE=([system_name]='XYZ' [dbname]='xyz_database' [dbusername]='user3')

# 存储数组名称的数组
declare -a databases=(DBONE DBTWO DBTHREE)

# 获取第一个数组名称
database="${databases[0]}"
echo "The dbname is ${$database[dbname]}"
echo "The dbname is ${$database}[dbname]"

输出:

./myscript.sh: ${$database[dbname]}: bad substitution
./myscript.sh: ${$database}[dbname]: bad substitution

原因:Bash 4.1.2不支持${$variable}这种嵌套变量替换语法,且没有命名引用特性来简化动态数组引用。

遍历动态数组的解决方案

针对遍历存储数组名称的数组这一需求,可使用间接扩展特性实现,无需依赖declare -n:

declare -rA DBONE=([system_name]='ABC' [dbname]='abc_database' [dbusername]='user1')
declare -rA DBTWO=([system_name]='DEF' [dbname]='def_database' [dbusername]='user2')
declare -rA DBTHREE=([system_name]='XYZ' [dbname]='xyz_database' [dbusername]='user3')

declare -a databases=(DBONE DBTWO DBTHREE)
for db in "${databases[@]}"; do
    # 构造关联数组的引用字符串
    ref="$db[dbname]"
    # 使用间接扩展获取对应键的值
    dbname="${!ref}"
    echo "The database is $db, and the dbname is $dbname"
done

输出:

The database is DBONE, and the dbname is abc_database
The database is DBTWO, and the dbname is def_database
The database is DBTHREE, and the dbname is xyz_database

也可以使用eval实现(注意:使用eval时需确保变量内容安全,避免注入风险):

declare -rA DBONE=([system_name]='ABC' [dbname]='abc_database' [dbusername]='user1')
declare -rA DBTWO=([system_name]='DEF' [dbname]='def_database' [dbusername]='user2')
declare -rA DBTHREE=([system_name]='XYZ' [dbname]='xyz_database' [dbusername]='user3')

declare -a databases=(DBONE DBTWO DBTHREE)
for db in "${databases[@]}"; do
    eval dbname=\"\${$db[dbname]}\"
    echo "The database is $db, and the dbname is $dbname"
done

内容的提问来源于stack exchange,提问作者Genki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 16:14:55