繁体   English   中英

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

[英]Bash, run multiple commands simultaneously, wait for N to finish before spawning more

好吧,所以我尝试了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

应该这样做,但我无法真正验证它是否以这种方式工作。 似乎只是立即将它们全部生成。 我假设终端的输出应为:回声1,回声2,回声3,回声4,回声5。然后回声6,回声7,回声8,回声9,回声10。

我只是想产生一个循环的5次迭代,等待它们完成,然后产生下一个5,等待它们完成,产生下一个5,依此类推,直到循环完成。

每次启动后台作业时,都要增加一个计数。 当该计数达到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让你知道当一个工作已完成,但不会有多少人完成)。为了保持机器忙,像一个工具xargsparallel是比较合适的。

从您的评论中还不清楚您想要什么。

但是,使用{= =}构造可以在参数中获得几乎所有内容。

仅在首次运行时附加.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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM