Bash,同时运行多个命令,等待N完成再产生更多

时间:2015-11-09 14:31:46

标签: linux multithreading bash shell

好吧,所以我尝试了gnu parallel并且有一些关于让它工作的怪癖让我无法使用。

最终,我希望能够做到这样的事情:

for modelplot in /${rfolder}/${mplotsfolder}/${mname}/$mscript.gs
do

for regionplot in $mregions
do
opengrads -bclx "${modelplot}.gs $regionplot ${plotimage} ${date} ${run} ${gribfile} ${modelplot}" && wait -n
done

done

但我似乎无法找到将后台进程的产生限制为特定数字的方法。有人提到过:

for i in {1..10}; do echo "${i} & (( count ++ > 5 )) && wait -n; done

应该这样做,但我无法真正验证它是否正常工作。它似乎只是瞬间产生它们。我假设终端的输出应该是:echo 1,echo 2,echo 3,echo 4,echo 5.然后echo 6,echo 7,echo 8,echo 9,echo 10。

我只是试图产生,比如5,循环的迭代,等待那些完成,然后产生接下来的5,等待那些完成,产生接下来的5等,直到循环完成。< / p>

2 个答案:

答案 0 :(得分:4)

每次启动后台作业时,都会增加计数。当该计数达到5(或其他)时,wait完成所有后台作业,然后将计数重置为0并继续启动后台作业。

p_count=0
for modelplot in /${rfolder}/${mplotsfolder}/${mname}/$mscript.gs; do
  for regionplot in $mregions; do
      opengrads -bclx "${modelplot}.gs $regionplot ${plotimage} ${date} ${run} ${gribfile} ${modelplot}" &
      if (( ++p_count == 5 )); then
          wait
          p_count=0
      fi
    done
  done
done

在shell中保留5个,而不是最多5个在后台运行的作业,这是非常棘手的。 (wait -n让您知道 作业何时完成,但已完成了多少。)为了让机器保持忙碌,请使用{{1}等工具}或xargs更合适。

答案 1 :(得分:0)

根据你的意见,目前还不清楚你想要什么。

但是使用{= =}构造,你几乎可以得到任何参数。

仅在第一次运行时附加.gs:

parallel echo {}'{= if($job->seq() == 1) { $_ = ".gs" } else { $_="" } =}' ::: a b c

仅在最后一次运行时附加.gs:

parallel echo {}'{= if($job->seq() == $Global::JobQueue->total_jobs() ) { $_ = ".gs" } else { $_="" } =}' ::: a b c

忽略评论并仅查看问题中的循环,解决方案是:

parallel --header : opengrads -bclx "{modelplot}.gs {regionplot} ${plotimage} ${date} ${run} ${gribfile} {modelplot}" ::: modelplot /${rfolder}/${mplotsfolder}/${mname}/$mscript.gs ::: regionplot $mregions