【问题标题】:Multiple (with one fixed) GNU-parallel arguments多个(一个固定的)GNU 并行参数
【发布时间】:2018-06-24 14:02:36
【问题描述】:

我使用 GNU-parallel 反复调用函数 foo。该函数有两个参数,一个文件名(在下面的示例中为a,保存在数组A 中)和一个过滤器数组(下面的Bb 作为B 的元素)。

该函数应该迭代 AB 的所有组合,但是,问题是,我实际上只使用并行迭代 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 = %s\n" $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 = %s\n" $a $b
    done
    echo "-----------------"
}
export -f foo2
export B

parallel foo ::: "${A[@]}"

结果

-----------------
-----------------

(显然是空的B)

【问题讨论】:

    标签: linux bash parallel-processing gnu-parallel


    【解决方案1】:

    您的问题源于 B 是一个数组。我以前从未见过将数组作为参数传递给函数,我不确定是否可以这样做。

    第二个问题是,虽然你可以导出函数和变量,但你不能在不作弊的情况下导出数组:Exporting an array in bash script

    GNU Parallel 使用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 = %s\n" $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[@]}"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-01
      • 2016-10-18
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多