如何并行运行2个及以上Bash/Unix脚本?求多种实现方案
如何并行运行多个Bash/Unix脚本?
没问题,并行运行多个Shell脚本是日常运维和自动化任务里很常见的需求,你看到的&确实是最基础的实现方式之一,下面我给你整理几种实用的启动方法,附带例子和细节说明:
1. 基础后台运行:& + wait
这是最直接的方式,在每个脚本命令末尾加上&,就能让脚本在后台异步运行,终端不会被阻塞。
基本用法
# 同时启动三个脚本到后台 ./script1.sh & ./script2.sh & ./script3.sh &
等待所有脚本完成
如果需要确保所有后台脚本都执行完毕后再继续后续操作,加上wait命令即可:
./script1.sh & ./script2.sh & ./script3.sh & # 等待所有后台进程结束 wait echo "所有脚本都执行完成啦!"
额外小技巧:
- 用
jobs命令可以查看当前终端的后台任务状态 - 用
$!可以获取上一个后台进程的PID,比如pid=$!,后续可以单独等待这个进程:wait $pid
2. 用xargs批量并行执行
如果你的脚本数量较多,或者需要从文件/列表中读取脚本路径,可以用xargs的-P参数指定并行运行的任务数。
从命令行指定脚本
# 最多同时运行2个脚本 echo -e "./script1.sh\n./script2.sh\n./script3.sh" | xargs -P 2 bash
从文件读取脚本列表
先把所有脚本路径写入scripts.txt(每行一个):
./script1.sh ./script2.sh ./script3.sh
然后执行:
# -P 3 表示同时运行3个任务,-I {} 用来替换脚本路径占位符 cat scripts.txt | xargs -P 3 -I {} bash {}
3. 用GNU Parallel(功能更强大的并行工具)
GNU Parallel是专门为并行任务设计的工具,比xargs更灵活,支持任务分发、输出控制、错误处理等高级功能。如果你的系统没有安装,用包管理器安装即可(比如apt install parallel或brew install parallel)。
基本用法
# 并行运行指定的脚本,默认根据CPU核心数确定并行数 parallel ::: ./script1.sh ./script2.sh ./script3.sh
指定并行数
# -j 4 表示最多同时运行4个任务 parallel -j 4 ::: ./script1.sh ./script2.sh ./script3.sh
从文件读取脚本列表
parallel < scripts.txt
4. 封装成主脚本统一管理
如果需要更精细的控制(比如单独跟踪每个脚本的PID、处理输出文件),可以写一个主脚本,把所有子脚本放到后台,再统一等待。
示例主脚本run_all.sh:
#!/bin/bash # 启动每个脚本到后台,并记录PID ./script1.sh > script1.log 2>&1 & pid1=$! echo "script1.sh 已启动,PID: $pid1" ./script2.sh > script2.log 2>&1 & pid2=$! echo "script2.sh 已启动,PID: $pid2" ./script3.sh > script3.log 2>&1 & pid3=$! echo "script3.sh 已启动,PID: $pid3" # 等待所有脚本结束 wait $pid1 $pid2 $pid3 # 检查每个脚本的执行状态 if [ $? -eq 0 ]; then echo "所有脚本执行成功!" else echo "部分脚本执行失败,请查看日志文件" fi
运行主脚本:bash run_all.sh
几个注意事项
- 输出冲突:多个后台脚本同时输出到终端会导致内容乱序,建议把每个脚本的输出重定向到单独日志文件(如上面例子中的
> script1.log 2>&1) - 资源限制:并行数不要超过系统的CPU核心数或可用内存,避免系统过载
- 错误处理:如果需要捕获脚本的执行错误,可以在子脚本中返回非0退出码,主脚本通过
wait后的$?或者单独检查每个PID的退出状态来判断
内容的提问来源于stack exchange,提问作者jake elias
相关产品推荐
相关产品推荐

