首页 文章

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

提问于
浏览
165

我有一个看起来像这样的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 回答

  • 80

    使用 wait 内置:

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

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

    来自GNU manual

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

  • 6

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

  • 296

    实际上, xargs can 并行运行命令 . 有一个特殊的 -P max_procs 命令行选项 . 见 man xargs .

  • 47

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

    wait
    

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

相关问题