我想在一些非平凡的设置中用bash填充一个关联数组。我有一个命令管道来为数组生成所需的输入。
这是一个最小/玩具示例:
declare -A mapping
seq 10 | while read i; do
key="key_$i"
val="val_$i"
echo "mapping[$key]=$val"
mapping["${key}"]="${val}"
done
echo "${mapping["key_1"]}"
echo "${mapping["key_2"]}"
在此示例中mapping
在while
内更改,但这些更改不会传播到全局命名空间。我认为这是因为while
在一个单独的子shell中工作,因此命名空间有分歧。
为了避免(我的建议)子壳的问题,我想出了以下内容:
declare -A mapping
while read i; do
key="key_$i"
val="val_$i"
echo "mapping[$key]=$val"
mapping["${key}"]="${val}"
done < <(seq 10)
echo "${mapping["key_1"]}"
echo "${mapping["key_2"]}"
因此,生成部分明确地进入子shell,而while
循环仅留在顶层。建筑工程。
我的问题是:有没有更好的方法来实现我的目标?而且,我对子壳的建议是否正确?如果是这样,为什么bash在第一种情况下使用子shell,而在第二种情况下不使用?
编辑:经过多一点挖掘后,问题主要是this one的重复。可以在http://mywiki.wooledge.org/BashFAQ/024 找到处理该问题的一系列选项答案 0 :(得分:1)
不确定这是否比第二个代码段更好,但解决第一个问题的方法是在管道后面使用子shell { ... }
:
declare -A mapping
seq 10 | {
while read i; do
key="key_$i"
val="val_$i"
echo "mapping[$key]=$val"
mapping["${key}"]="${val}"
done
echo "${mapping["key_1"]}"
echo "${mapping["key_2"]}"
}