Bash脚本并行处理有限数量的命令

时间:2013-10-23 13:33:25

标签: linux bash shell

我有一个看起来像这样的bash脚本:

#!/bin/bash
wget LINK1 >/dev/null 2>&1
wget LINK2 >/dev/null 2>&1
wget LINK3 >/dev/null 2>&1
wget LINK4 >/dev/null 2>&1
# ..
# ..
wget LINK4000 >/dev/null 2>&1

但是处理每一行直到命令完成然后移动到下一行是非常耗时的,我想一次处理20行,然后当它们完成另外20行处理时。

我想wget LINK1 >/dev/null 2>&1 &将命令发送到后台并继续,但这里有4000行这意味着我会遇到性能问题,更不用说我应该从多少进程开始了同时这不是一个好主意。

我现在正在考虑的一个解决方案是检查其中一个命令是否仍在运行,例如在20行后我可以添加此循环:

while [  $(ps -ef | grep KEYWORD | grep -v grep | wc -l) -gt 0 ]; do
sleep 1
done

当然在这种情况下,我需要追加&到了最后!但我觉得这不是正确的做法。

那么我如何实际将每20行组合在一起并等待它们完成,然后再转到接下来的20行,这个脚本是动态生成的,所以我可以在生成它的时候做我想要的任何数学运算,但是它可以做到不必使用wget,它只是一个例子,所以任何具体的解决方案都不会对我有任何帮助。

4 个答案:

答案 0 :(得分:308)

使用内置的wait

process1 &
process2 &
process3 &
process4 &
wait
process5 &
process6 &
process7 &
process8 &
wait

对于上面的示例,将在后台启动4个进程process1 ... process4,并且shell将等到这些进程完成后再开始下一组。

来自GNU manual

wait [jobspec or pid ...]
     

等到每个进程ID pid或作业规范jobspec指定的子进程退出并返回最后一个的退出状态   命令等待。如果给出了作业规范,则作业中的所有进程   等待。如果没有给出参数,则所有当前活动的子项   等待进程,返回状态为零。如果没有   jobspec和pid指定shell的活动子进程,   返回状态为127。

答案 1 :(得分:83)

parallel。它的语法类似于xargs,但它并行运行命令。

答案 2 :(得分:55)

事实上,xargs 可以为您并行运行命令。有一个特殊的-P max_procs命令行选项。请参阅man xargs

答案 3 :(得分:7)

您可以运行20个进程并使用命令:

wait

您的脚本将在所有后台作业完成后等待并继续。