You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

获取并行运行的多个Bash脚本的退出码并实现失败即退出

Bash 解决方案

你可以借助 Bash 的进程ID(PID)追踪和信号处理机制实现需求,具体脚本如下:

#!/bin/bash

# 启动所有脚本并记录PID
pids=()
./script1.sh & pids+=($!)
./script2.sh & pids+=($!)
./script3.sh & pids+=($!)
./script4.sh & pids+=($!)

# 定义清理函数:终止所有子进程并退出
cleanup() {
    kill "${pids[@]}" 2>/dev/null
    exit 1
}

# 捕获中断信号,确保异常退出时清理进程
trap cleanup SIGINT SIGTERM

# 等待任意一个子进程结束,获取其退出码
wait -n "${pids[@]}"
exit_code=$?

# 若退出码非0,触发清理逻辑
if [ $exit_code -ne 0 ]; then
    cleanup
fi

# 等待剩余进程正常完成
wait

核心逻辑:

  • 用数组保存所有后台进程的PID,方便统一管理
  • wait -n 会等待第一个结束的进程,直接拿到它的退出状态
  • 一旦检测到非0退出码,立即调用cleanup杀掉所有子进程并退出
  • 信号捕获确保手动中断(比如Ctrl+C)时也能清理残留进程
Python 解决方案

如果更倾向用Python实现,可以通过subprocess模块启动进程并轮询监控状态:

import subprocess
import time
import os
import signal

# 启动所有脚本,保存进程实例
processes = []
script_paths = ["./script1.sh", "./script2.sh", "./script3.sh", "./script4.sh"]

for path in script_paths:
    proc = subprocess.Popen(path, shell=True)
    processes.append(proc)

try:
    while True:
        for proc in processes:
            exit_code = proc.poll()
            # 进程已结束且退出码非0
            if exit_code is not None and exit_code != 0:
                print(f"脚本 {proc.args} 执行失败,退出码 {exit_code},终止所有进程")
                # 终止所有未结束的进程
                for p in processes:
                    if p.poll() is None:
                        os.kill(p.pid, signal.SIGTERM)
                exit(1)
        time.sleep(0.1)  # 降低轮询频率,减少CPU占用
except KeyboardInterrupt:
    # 处理手动中断,清理进程
    print("收到中断信号,终止所有进程")
    for p in processes:
        if p.poll() is None:
            os.kill(p.pid, signal.SIGTERM)
    exit(1)

核心逻辑:

  • 用subprocess.Popen启动每个脚本,保存进程对象
  • 循环调用proc.poll()检查进程状态,返回None表示进程仍在运行
  • 一旦发现某个进程退出且退出码非0,立即终止所有存活的子进程
  • 捕获KeyboardInterrupt确保手动中断时能正确清理进程

内容的提问来源于stack exchange,提问作者Mayank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:01:15