shell中的并行赋值

时间:2014-07-12 02:41:17

标签: bash shell

我有以下bash脚本:

for (( i = 1; i <= $3; i++ ))
do
    x=$($1 bench 4 2>&1|grep "Nodes\/second"|sed "s/.*: \([0-9]*\)/\1/") &
    y=$($2 bench 4 2>&1|grep "Nodes\/second"|sed "s/.*: \([0-9]*\)/\1/")
    echo $x, $y
done

我使用3个参数运行:

  1. 第一个程序:$($1 bench 4 2>&1|grep "Nodes\/second"|sed "s/.*: \([0-9]*\)/\1/")的结果是一个数字。
  2. 第二个节目。同上。
  3. 迭代次数
  4. 关键是我要并行运行x=...y=...,这就是我使用&符号的原因。这很重要,并行化必须以这种方式完成(对x和y运行第一次迭代,在第二次迭代之前等待两者完成等)。

    此脚本的结果是未分配x,只有y为:

    $ ./bench.sh ./Stockfish/cerr ./Stockfish/master 50
    , 2417071
    , 2440128
    , 2439481
    etc.
    

    为什么?

1 个答案:

答案 0 :(得分:3)

问题是你必须把它们都放在后台(所以把它放在两行的末尾)然后wait才能完成作业 - 如果不是你不确定第一个作业在第二次迭代开始之前完成。

第二个问题是您无法使用x$(...)&从后台作业返回输出,因此您必须将输出重定向到文件,然后在作业完成时读取文件输出。

for (( i = 1; i <= $3; i++ ))
do
    ($1 bench 4 2>&1|grep "Nodes\/second"|sed "s/.*: \([0-9]*\)/\1/" >/tmp/x) &
    ($2 bench 4 2>&1|grep "Nodes\/second"|sed "s/.*: \([0-9]*\)/\1/" >/tmp/y) & 
    wait
    read x </tmp/x
    read y </tmp/y
    echo $x, $y
done

作为额外的奖励答案,请尝试阅读xargs的手册页 - 在大多数情况下,它会使这些循环变得非常不必要且更安全。