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

如何在Bash脚本中维持两个进程存活并在崩溃后自动重启?

解决方案:用PID跟踪实现多进程守护

核心思路是记录每个进程的PID,通过kill -0 $PID精准检查进程是否存活(这个命令仅验证进程存在,不会发送任何信号,比ps | grep靠谱得多),同时后台启动两个进程,循环监控并重启崩溃的进程。

以下是完整脚本:

#!/bin/bash

# 配置参数
BIN1="./$BINNAME"
LOG1="$LOGNAME"
PID1="/tmp/process1.pid"
STOP_FILE1="$FILENAME"

BIN2="./$BINNAMEPROC"
LOG2="$LOGNAMEPROC"
PID2="/tmp/process2.pid"
STOP_FILE2="$FILENAMEPROC"

# 启动单个进程的函数
start_process() {
    local bin=$1
    local log=$2
    local pid_file=$3
    # 启动进程并后台运行,将PID写入文件
    $bin >> "$log" 2>&1 &
    echo $! > "$pid_file"
    echo "Started $bin with PID $(cat $pid_file)"
}

# 检查进程是否存活
is_running() {
    local pid=$1
    # kill -0 不发送信号,仅检查进程是否存在
    kill -0 "$pid" 2>/dev/null
    return $?
}

# 清理函数:脚本退出时杀死子进程并删除PID文件
cleanup() {
    echo "Stopping processes..."
    [ -f "$PID1" ] && kill $(cat "$PID1") 2>/dev/null
    [ -f "$PID2" ] && kill $(cat "$PID2") 2>/dev/null
    rm -f "$PID1" "$PID2"
    exit 0
}

# 捕获退出信号,执行清理
trap cleanup SIGINT SIGTERM

# 初始化启动两个进程
start_process "$BIN1" "$LOG1" "$PID1"
start_process "$BIN2" "$LOG2" "$PID2"

# 主监控循环
while true; do
    # 检查第一个进程的终止文件,如果不存在则停止进程并退出
    if [ ! -f "$STOP_FILE1" ]; then
        echo "Stop file $STOP_FILE1 removed, stopping $BIN1"
        kill $(cat "$PID1") 2>/dev/null
        rm -f "$PID1"
        # 如果第二个进程的终止文件也不存在,直接退出
        [ ! -f "$STOP_FILE2" ] && cleanup
    else
        # 检查第一个进程是否存活,不存活则重启
        if [ -f "$PID1" ]; then
            PID=$(cat "$PID1")
            if ! is_running "$PID"; then
                echo "$BIN1 crashed, restarting..."
                start_process "$BIN1" "$LOG1" "$PID1"
            fi
        else
            # PID文件丢失,重新启动
            echo "PID file $PID1 missing, restarting $BIN1..."
            start_process "$BIN1" "$LOG1" "$PID1"
        fi
    fi

    # 检查第二个进程的终止文件和存活状态,逻辑同上
    if [ ! -f "$STOP_FILE2" ]; then
        echo "Stop file $STOP_FILE2 removed, stopping $BIN2"
        kill $(cat "$PID2") 2>/dev/null
        rm -f "$PID2"
        [ ! -f "$STOP_FILE1" ] && cleanup
    else
        if [ -f "$PID2" ]; then
            PID=$(cat "$PID2")
            if ! is_running "$PID"; then
                echo "$BIN2 crashed, restarting..."
                start_process "$BIN2" "$LOG2" "$PID2"
            fi
        else
            echo "PID file $PID2 missing, restarting $BIN2..."
            start_process "$BIN2" "$LOG2" "$PID2"
        fi
    fi

    sleep 1
done

关键细节说明:

  • PID跟踪:每个进程启动后把PID写入临时文件,后续通过PID直接验证进程状态,完全避免ps | grep的误判(比如匹配到grep进程本身)。
  • kill -0检查存活:这是shell中检查进程是否存在的标准方法,仅返回状态码,不影响进程运行。
  • 后台运行:用&将进程放到后台,确保两个进程同时启动。
  • 终止文件逻辑:只要对应进程的终止文件存在,就持续监控;文件删除后停止对应进程,若两个文件都删除则退出脚本。
  • 清理陷阱:捕获Ctrl+C等退出信号,确保脚本退出时能正确停止子进程并清理PID文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 04:07:41