如何在Bash中始终保持3个脚本并行运行(共6个脚本)
实现始终维持3个并行进程的Bash脚本方案
这需求我之前做批量任务的时候经常碰到,要从“分两批并行”改成“始终保持固定数量进程跑,跑完一个补一个”,其实有几种实用的方法,我给你详细说下:
方法一:用xargs快速实现(最简单)
xargs本身就支持指定并行进程数(-P参数),它会自动帮你维持这个数量的进程,一个结束就立刻启动下一个。把所有要执行的命令列出来,通过管道传给xargs就行:
# 把所有命令按行输出,交给xargs以3个并行进程执行 echo -e "command1\ncommand2\ncommand3\ncommand4\ncommand5\ncommand6" | xargs -I {} -P 3 bash -c "{}"
关键参数解释:
-I {}:把每行的命令内容替换成{},作为后续命令的参数-P 3:指定最多同时运行3个进程bash -c "{}":用来执行每个命令(如果命令本身是简单命令,也可以直接用,但加bash -c能兼容带参数或特殊字符的命令)
如果命令太多,也可以把它们写到一个文本文件里(比如commands.txt,每行一个命令),然后用:
xargs -I {} -P 3 bash -c "{}" < commands.txt
方法二:自己写Bash脚本管理进程(更灵活)
如果需要更精细的控制(比如记录日志、处理异常),可以自己写脚本监控后台进程。这里分两种情况:
情况1:Bash 4.3+版本(支持wait -n)
wait -n可以等待任意一个后台进程完成,效率很高:
#!/bin/bash # 把所有要执行的命令放到数组里 commands=( "command1" "command2" "command3" "command4" "command5" "command6" ) max_parallel=3 current_idx=0 # 先启动第一批3个进程 for ((i=0; i<max_parallel && i<${#commands[@]}; i++)); do echo "启动命令: ${commands[$i]}" ${commands[$i]} & current_idx=$((current_idx + 1)) done # 循环监控,完成一个就补一个 while ((current_idx < ${#commands[@]})); do # 等待任意一个后台进程结束 wait -n echo "有一个进程执行完成,启动下一个命令..." echo "启动命令: ${commands[$current_idx]}" ${commands[$current_idx]} & current_idx=$((current_idx + 1)) done # 等待最后一批所有进程完成 wait echo "所有命令执行完毕!"
情况2:旧版本Bash(不支持wait -n)
如果你的Bash版本低于4.3,可以通过循环检查后台进程数的方式实现,兼容性更好:
#!/bin/bash commands=( "command1" "command2" "command3" "command4" "command5" "command6" ) max_parallel=3 current_idx=0 while ((current_idx < ${#commands[@]})); do # 统计当前运行的后台进程数 running_count=$(jobs -p | wc -l) if ((running_count < max_parallel)); then echo "启动命令: ${commands[$current_idx]}" ${commands[$current_idx]} & current_idx=$((current_idx + 1)) else # 短暂休眠,避免循环占用过多CPU sleep 0.5 fi done # 等待所有剩余进程完成 wait echo "所有命令执行完毕!"
注意事项
- 如果命令包含空格、特殊字符(比如
>、|),一定要在数组里用引号正确包裹,比如"echo 'hello' > output.txt" - 如果需要捕获命令的输出或错误,可以在执行命令时重定向,比如
${commands[$current_idx]} > ${current_idx}.log 2>&1 &
内容的提问来源于stack exchange,提问作者user9159310
相关产品推荐
相关产品推荐

