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
当所有的后台作业完成后,你的脚本将会等待并继续。