PAYATHON 2026

Bash 关联数组使用变量下标时,应该如何添加引号?

数据小许

结论:示例中的两种写法都正确

对于已通过 declare -A prices 声明的关联数组,在题目中的读取场景下,下面两种写法效果相同,都会使用 item 的完整值 peanut butter 作为键:

price="${prices[$item]}"
price="${prices["$item"]}"

可以使用第一种写法。下标中的 $item 不需要额外加双引号,保留整个数组元素展开外面的双引号即可,写法也更简洁。

为什么含空格的下标不会被拆开?

关联数组下标有自己的展开规则。在 ${prices[$item]} 中,Bash 不会对下标展开的结果执行普通命令参数位置上的单词分割(word splitting)和路径名展开(pathname expansion),因此 peanut butter 会作为一个完整的键用于查找。

第二种写法中,内部双引号属于下标表达式的引用语法,不会成为键名的一部分,在这个场景下也不会改变查找结果。

两处引号的作用不同:下标内部的引号涉及键的处理,整个 ${prices[...]} 外面的引号涉及取出元素后如何使用它的值。

推荐写法

读取时可以使用第一种形式。输出时保留引号,并使用 printf:

declare -A prices=(
    [apple]=1.99
    [banana]=2.99
    ["peanut butter"]=4.99
)

item="peanut butter"
price="${prices[$item]}"
printf '%s\n' "$price"

这里使用 [key]=value 形式初始化关联数组,可以直接看出每个键对应的值。

原示例中的 echo $price 没有引用 $price。对于 4.99,这不会造成可见差异;如果元素值包含空格或通配符,未引用的展开结果就可能发生单词分割或路径名展开。

也可以直接输出数组元素:

printf '%s\n' "${prices[$item]}"

注意适用范围

普通变量赋值语句的右侧不会执行单词分割和路径名展开,因此在 price="${prices[$item]}" 这条赋值语句中,外层双引号并不是防止值被拆分的必要条件。保留它们有助于保持一致的引用习惯;将展开结果作为 printf 等命令的参数时,则应加上双引号。

以上结论针对关联数组元素的参数展开。索引数组的下标按算术表达式处理,不能直接套用这里的解释;unset 等命令接收数组元素名称时,也应按相应命令的语法处理引号。

备注:内容仅供参考。