本文目录导读:

- 方案一:使用 while 循环 + 检查进程(纯 Shell 脚本,通用性强)
- 方案二:针对特定端口/URL 的健康检查(适合 Web 服务)
- 方案三:使用 crontab(定时检查,最低资源占用)
- 方案四:最推荐——使用 systemd 的自动重启功能(Linux 服务级)
- 选择建议
- 重要注意事项
实现进程自动重启的脚本,最常用的方法是通过循环检测进程状态,或者利用系统服务管理工具(如 systemd、Supervisor)来实现。
以下我为你提供 4 种常见的脚本实现方案,按推荐程度排序:
使用 while 循环 + 检查进程(纯 Shell 脚本,通用性强)
这种方式适合在容器内或简单的后台任务中使用。
原理:脚本会持续检查指定进程名称是否在运行,如果不在,就启动它。
#!/bin/bash
# 配置区
PROCESS_NAME="nginx" # 你要监控的进程名
COMMAND="/usr/sbin/nginx" # 启动该进程的命令(最好使用绝对路径)
CHECK_INTERVAL=10 # 检查间隔(秒)
# 主循环
while true; do
# 检查进程是否存在(-x 表示精确匹配进程名,-c 统计数量)
count=$(pgrep -x -c "$PROCESS_NAME")
if [ "$count" -eq 0 ]; then
echo "[$(date)] 检测到进程 $PROCESS_NAME 未运行,正在启动..."
# 执行启动命令(如果需要后台运行,加上 &)
$COMMAND &
# 可选:等待几秒确认启动成功
sleep 2
if pgrep -x "$PROCESS_NAME" > /dev/null; then
echo "[$(date)] 进程 $PROCESS_NAME 重启成功"
else
echo "[$(date)] 进程 $PROCESS_NAME 启动失败,请检查错误日志"
fi
fi
sleep $CHECK_INTERVAL
done
如何运行:
# 保存为 auto_restart.sh chmod +x auto_restart.sh # 后台运行(注意:关闭终端后需用 nohup 或 screen) ./auto_restart.sh & # 更稳妥的方式使用 nohup 保持后台运行 nohup ./auto_restart.sh > restart.log 2>&1 &
针对特定端口/URL 的健康检查(适合 Web 服务)
如果进程运行了但卡死(听不到端口),上面基于进程名的方法可能误判,下面这个脚本会检测端口或 HTTP 响应。
#!/bin/bash
# 配置区
MONITOR_URL="http://localhost:8080/health" # 健康检查 URL
RESTART_COMMAND="systemctl restart myapp" # 重启命令
CHECK_INTERVAL=15 # 检查间隔(秒)
# 如果检查失败次数累计达到阈值,才执行重启,防止误判
FAILURE_THRESHOLD=3
failure_count=0
while true; do
# 使用 curl 检查服务健康状态
# -f 表示失败时返回错误码,-s 静默,-o 忽略输出
if curl -f -s -o /dev/null "$MONITOR_URL"; then
# 健康检查成功
if [ $failure_count -gt 0 ]; then
echo "[$(date)] 服务恢复正常,重置失败计数"
fi
failure_count=0
else
# 健康检查失败
((failure_count++))
echo "[$(date)] 健康检查失败 (第 $failure_count 次)"
if [ $failure_count -ge $FAILURE_THRESHOLD ]; then
echo "[$(date)] 连续失败 $FAILURE_THRESHOLD 次,执行重启..."
$RESTART_COMMAND
failure_count=0 # 重启后重置
sleep 10 # 给系统一点时间恢复
fi
fi
sleep $CHECK_INTERVAL
done
使用 crontab(定时检查,最低资源占用)
如果你不想让一个脚本一直跑(占用一个进程),可以用 cron 定时每分钟检查一次。
脚本片段 (/usr/local/bin/check_myapp.sh):
#!/bin/bash
PROCESS_NAME="myapp"
if ! pgrep -x "$PROCESS_NAME" > /dev/null; then
echo "[$(date)] 进程 $PROCESS_NAME 已退出,cron 触发重启" >> /var/log/restart.log
/usr/local/bin/start_myapp.sh
fi
设置 crontab(编辑:crontab -e):
# 每分钟执行一次检查 * * * * * /usr/local/bin/check_myapp.sh
最推荐——使用 systemd 的自动重启功能(Linux 服务级)
如果你的进程是系统服务,不要自己写脚本,直接用 systemd 是最稳定、最专业的方式。
示例 Service 文件 (/etc/systemd/system/myapp.service):
[Unit] Description=My Application After=network.target [Service] Type=simple User=www-data WorkingDirectory=/opt/myapp ExecStart=/opt/myapp/myapp_binary Restart=always # 关键:总是自动重启 RestartSec=5 # 重启前等待 5 秒 StartLimitInterval=0 # 不限制重启次数 [Install] WantedBy=multi-user.target
使用:
# 重新加载 systemd sudo systemctl daemon-reload # 启动服务 sudo systemctl start myapp # 启用开机自启 sudo systemctl enable myapp # 查看状态(会显示重启次数) sudo systemctl status myapp
选择建议
| 场景 | 推荐方案 |
|---|---|
| 你的进程是 Linux 标准服务 | 方案四(systemd) - 最专业,日志/资源管理都好 |
| 在 Docker 容器内运行 | 方案一(while 循环) 或 Docker 自带的 restart: always |
| 只想临时用一下,不想改系统配置 | 方案一 或 方案三(crontab) |
| 需要检测服务是否真正可用(能返回数据) | 方案二(健康检查) |
| 需要监控多个进程 | 可以用 Supervisor(比脚本更强大) |
重要注意事项
- 避免无限重启:建议在脚本中加入重启次数计数,1 分钟内重启超过 5 次就停止,避免服务“死亡循环”。
- 日志输出:在脚本中加
echo [$(date)],方便排查问题。 - 权限问题:如果启动命令需要
sudo,记得配置NOPASSWD或在脚本中合理使用。 - 进程名冲突:
pgrep -x的-x参数表示精确匹配,避免误杀或误判同名字的其他进程。
如果你能告诉我你具体是用来监控什么进程(Java 应用、Node.js、数据库、Python 脚本),我可以帮你调整出最合适的脚本变体。