我使用 GNU-parallel 来重复调用函数foo
。该函数有两个参数,一个文件名(在下面的示例中a
,保存在数组A
中)和一个过滤器数组(B
下面,b
作为B
的元素)。
该函数应该遍历A
和B
的所有组合,但是,问题是,我实际上只使用并行来迭代A
,同时为每个函数调用提供B
。
作为最小示例:
#!/bin/bash
A=("1" "2" )
B=("X" "Y")
foo() {
a=$1 # a single element of A
B=$2 # the whole array B
for b in "${B[@]}"; do
printf "a = %s; b = %sn" $a $b
done
echo "-----------------"
}
export -f foo
# goal:
echo "Sequential (aka, the target) ==="
for a in "${A[@]}"; do
foo $a $B
done
结果
Sequential (aka, the target) ===
a = 1; b = X
a = 1; b = Y
-----------------
a = 2; b = X
a = 2; b = Y
-----------------
请注意,我们没有对每个组合进行一次调用,而是只对A
每个组合进行一次调用,然后在函数中迭代B
。
并行尝试:
尝试 1
parallel foo ::: "${A[@]}" ::: "${B}"
结果在
a = 1; b = X
-----------------
a = 2; b = X
-----------------
(缺少B的第二个参数)
尝试 2
parallel foo ::: "${A[@]}" ::: "${B[@]}"
结果在
a = 1; b = X
-----------------
a = 1; b = Y
-----------------
a = 2; b = X
-----------------
a = 2; b = Y
-----------------
(每个组合一个调用,而不是每个 A 一个调用,然后迭代 B)
我已经浏览了手册和SO,但找不到解决方案。
编辑
我觉得当我直接导出数组 B 时它应该可以工作,但也没有得到任何结果
foo2() {
a=$1 # a single element of A
# B=$2 # the whole array B
for b in "${B[@]}"; do
printf "a = %s; b = %sn" $a $b
done
echo "-----------------"
}
export -f foo2
export B
parallel foo ::: "${A[@]}"
结果在
-----------------
-----------------
(显然是空的B)
你的问题源于B
是一个数组。我以前从未见过数组作为参数传递给函数,我不确定它是否可以完成。
第二个问题是,虽然您可以导出函数和变量,但您无法在不作弊的情况下导出数组: 在 bash 脚本中导出数组
GNU 并行使得通过使用env_parallel
来作弊变得容易。这会将完整环境导出到运行命令的 shell:数组、变量、别名和函数。它甚至可以在远程运行命令时这样做。
env_parallel
在过去一年中改进了很多,因此如果您拥有的版本导致问题,请升级。
#!/bin/bash
A=("1" "2" )
B=("X" "Y")
foo() {
a=$1 # a single element of A
# B=$2 # the whole array B
for b in "${B[@]}"; do
printf "a = %s; b = %sn" $a $b
done
echo "-----------------"
}
# If you have earlier run 'env_parallel --install'
# to activate env_parallel in your shell
# this should work.
env_parallel foo ::: "${A[@]}"
# If you have not, then this should work:
. `which env_parallel.bash`
env_parallel foo ::: "${A[@]}"