如何在Bash脚本中运行多并发进程,实现任一退出则全部终止
Bash实现并发进程/命令的协同终止
核心实现思路
借助Bash的作业控制与信号机制,当任意子进程或命令退出时,立即向其余所有并发任务发送终止信号(如SIGTERM),确保所有任务同步停止。该方案依赖Bash 4.3及以上版本提供的wait -n命令,它可以精准等待第一个退出的子进程。
场景1:并发运行多个独立进程
比如同时启动ping、sleep和自定义脚本,只要其中一个退出,另外两个立刻终止:
#!/bin/bash # 定义要并发运行的进程命令 processes=( "ping -c 5 google.com" "sleep 10" "./my_custom_script.sh" ) # 存储子进程PID的数组 pids=() # 启动所有进程并记录PID for cmd in "${processes[@]}"; do echo "启动进程: $cmd" eval "$cmd" & pids+=($!) done # 等待第一个进程退出 wait -n # 杀死所有剩余子进程 echo "检测到进程退出,终止所有剩余进程..." kill "${pids[@]}" 2>/dev/null # 等待所有进程彻底退出 wait "${pids[@]}" 2>/dev/null echo "所有进程已终止"
场景2:并发运行一系列多步骤命令
如果每个并发任务是多步骤的命令序列,可将其封装成函数后后台执行,逻辑同样适用:
#!/bin/bash # 定义各个并发任务函数 task1() { echo "任务1开始: 下载文件..." curl -O https://example.com/large-file.zip echo "任务1完成/失败" } task2() { echo "任务2开始: 处理数据..." for i in {1..15}; do echo "任务2进度: $i/15" sleep 1 done echo "任务2完成" } task3() { echo "任务3开始: 日志监控..." tail -f /var/log/syslog | grep -m 5 "error" echo "任务3检测到错误,退出" } # 启动所有任务并记录PID pids=() task1 & pids+=($!) task2 & pids+=($!) task3 & pids+=($!) # 等待第一个任务退出 wait -n # 终止所有剩余任务 echo "有任务退出,终止全部任务..." kill "${pids[@]}" 2>/dev/null # 清理残留进程 wait "${pids[@]}" 2>/dev/null echo "所有任务已停止"
关键细节说明
wait -n:核心命令,等待第一个子进程退出后立即触发后续终止逻辑。kill "${pids[@]}":向所有记录的子进程PID发送SIGTERM信号,2>/dev/null用于忽略"进程已不存在"的冗余错误提示。- 末尾的
wait:确保所有进程彻底退出,避免脚本提前结束导致僵尸进程残留。
内容的提问来源于stack exchange,提问作者Carl Patenaude Poulin
相关产品推荐
相关产品推荐

