如何使GNU并行加载变量

时间:2016-10-10 19:51:22

标签: bash parallel-processing gnu gnu-parallel

我正在尝试让GNU parallel读取文件并从中加载BASH变量,然后对它们执行一些操作。

例如:

ls -1 build*/*.properties | parallel source {}; echo "var set to: $foo";

每个* .properties文件的格式为:

foo=bar
var=blah

然而,当我尝试使用“source”或“。”时。要将文件中的变量作为Bash变量加载,从文件中设置变量似乎不起作用。

$ ls -1 build*/*.properties | parallel source {} ; echo "variable set to $foo";
variable set to

谁能告诉我这里我做错了什么?我知道必须有一个简单的方法来做到这一点。

2 个答案:

答案 0 :(得分:2)

第一个错误是:

ls -1 build*/*.properties | parallel source {}; echo "var set to: $foo";

被Bash解释为:

ls -1 build*/*.properties | parallel source {}
echo "var set to: $foo";

这显然不是你想要的。

改进是引用;

ls -1 build*/*.properties | parallel "source {}; echo var set to: $foo";

但它仍然没有做正确的事情,因为变量是用双引号插值的。所以GNU Parallel没有看到字符串$ foo。在GNU Parallel启动之前,Bash用$ foo的内容替换$ foo。所以我们需要强制Bash不要用$ foo:

的值替换$ foo
ls -1 build*/*.properties | parallel 'source {}; echo "var set to: $foo"';

或者同样好:

ls -1 build*/*.properties | parallel source {}\; echo \"var set to: \$foo\"

如果你发现引用是hazzle,那么使用Bash函数:

mybuild() {
    source "$1"
    echo "var set to: $foo"
}
export -f mybuild
ls -1 build*/*.properties | parallel mybuild {}
# or shorter:
parallel mybuild ::: build*/*.properties

答案 1 :(得分:1)

parallel是一个程序,而不是内置命令,因此它会将变量提供给OK,但仅限于其上下文。

变量不会传播到父进程,所以你不能这样做。

你坚持使用

的非并行版本
for i in build*/*.properties
do
   source $i
done

(注意:如果你执行source $i &同样的问题:创建了另一个进程并且你丢失了结果)