一尘不染

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

linux

我有一个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的解决方案都不会给我带来任何好处。


阅读 317

收藏
2020-06-02

共1个答案

一尘不染

使用wait内置的:

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

对于上面的例子中,4个进程process1...... process4将在后台启动,并在外壳会等到这些都开始下一组之前完成。

GNU手册

wait [jobspec or pid ...]

等待直到由每个进程ID
pid或作业规范jobspec指定的子进程退出,并返回等待的最后一条命令的退出状态。如果给出了作业说明,则将等待作业中的所有过程。如果未提供任何参数,则将等待所有当前活动的子进程,并且返回状态为零。如果jobspec和pid均未指定外壳的活动子进程,则返回状态为127。

2020-06-02