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行,这意味着我将遇到性能问题,更不用说我应该同时启动多少个进程受到限制,因此这不是一个好主意。

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

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

当然,在这种情况下,我需要附加&;排到队尾!但我觉得这不是正确的做法。

因此,我如何将每20行组合在一起,并等待它们完成,然后再转到下一个20行,这个脚本是动态生成的,因此我可以在生成时对它进行任何数学运算,但它不一定要使用wget,它只是一个示例,因此任何特定于wget的解决方案都不会对我有任何好处。

209663 次浏览

使用内置的wait

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

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

GNU手册

wait [jobspec or pid ...]

等待每个进程ID、PID或作业规范jobspec指定的子进程退出,并返回最后一个进程的退出状态。 命令等待。如果给出了作业规范,则作业中的所有进程 都在等待。如果未给定参数,则所有当前活动的子级 等待进程,返回状态为零。如果两者都没有 JobSpec NOR PID指定shell的活动子进程, 返回状态为127。

请参阅平行的。其语法类似于xargs,但它以并行方式运行命令。

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

wait

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

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