bash:从命令管道访问全局变量

时间:2016-12-08 10:31:46

标签: bash pipe pipeline

我想在一些非平凡的设置中用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"]}"

在此示例中mappingwhile内更改,但这些更改不会传播到全局命名空间。我认为这是因为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

找到处理该问题的一系列选项

1 个答案:

答案 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"]}"
}