Bash 如何使GNU与加载变量并行

Bash 如何使GNU与加载变量并行,bash,parallel-processing,gnu,gnu-parallel,Bash,Parallel Processing,Gnu,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 sou

我试图读入一个文件并从中加载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

有人能告诉我我做错了什么吗?我知道一定有一个简单的方法可以做到这一点。

parallel
是一个程序,不是一个内置命令,所以它可以为变量提供源代码,但只能在其上下文中

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

你被困在非并行版本中

for i in build*/*.properties
do
   source $i
done

(注意:如果您执行
source$i&
,则会出现相同的问题:创建了另一个进程,您将丢失结果)

第一个错误是:

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。在gnuparallel启动之前,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\"
如果您发现引用是一个骗局,那么请使用Bash函数:

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

您希望/需要对这些变量做什么?这些变量指定要部署的“服务”。因此,它应该遍历所有具有*.properties文件的子目录,加载它们的变量,包括“service\u name”,然后对每个子目录执行“deploy$service\u name”。谢谢!如果我将逻辑更改为只接受参数(属性文件的路径)的bash脚本,然后bash脚本加载变量并运行命令,那么它会工作吗?这应该意味着它是在同一个上下文中运行的,不是吗?谢谢!这对我有用。真不敢相信仅仅在命令周围加上单引号就可以让“源”命令工作。你明白为什么吗?嗯。。。。老实说,我不知道。这与单引号和双引号以及Bash如何处理它们有关吗?