[英]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
让你知道当一个工作已完成,但不会有多少人完成)。为了保持机器忙,像一个工具xargs
或parallel
是比较合适的。
从您的评论中还不清楚您想要什么。
但是,使用{= =}
构造可以在参数中获得几乎所有内容。
仅在首次运行时附加.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.