197

我有一个看起来像这样的 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 的解决方案都不会对我有任何好处。

4

4 回答 4

332

使用wait内置:

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

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

来自GNU 手册

wait [jobspec or pid ...]

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

于 2013-10-23T13:35:42.290 回答
97

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

于 2013-10-23T13:38:57.070 回答
72

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

于 2016-06-27T06:41:12.060 回答
7

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

wait

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

于 2013-10-23T13:41:18.573 回答