如何在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
相关产品推荐
相关产品推荐

