Bash脚本并行处理命令

我有一个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行,这意味着我会有性能问题,更不用说限制在多less个进程中我应该同时开始,所以这不是一个好主意。

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

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

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

那么我怎样才能真正把每一条20条线组合在一起,然后等待它们到达下一条20条线呢?这个脚本是dynamic生成的,所以我可以在数据生成时做任何我想要的数据,但是它不必使用wget,这只是一个例子,所以任何wget特定的解决scheme都不会对我有任何好处。

使用内置的wait

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

对于上面的例子来说,4个进程process1 .. process4将在后台启动,并且shell将在启动下一个set之前等待这些进程完成。

从手册 :

 wait [jobspec or pid ...] 

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

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

实际上, xargs 可以为你并行运行命令。 有一个特殊的-P max_procs命令行选项。 看到man xargs

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

 wait 

当所有的后台作业完成后,你的脚本将会等待并继续。