Shell 脚本实现服务自动重启的核心是通过循环检测进程状态,发现进程消失后执行启动命令。这种方法适合轻量级任务或无法使用 systemd 的环境,生产环境建议优先配置 systemd 的 Restart 策略以避免脚本自身成为单点故障。
先说结论:Shell 脚本监控适合临时方案或简单守护,长期稳定运行推荐使用 systemd 原生配置。
- 适合:无法修改系统服务配置、临时测试脚本、用户态进程监控。
- 先看:确认进程识别方式(PID 文件、端口或进程名),避免误杀或漏检。
- 建议:设置重启间隔 sleep 时间,防止进程启动失败导致脚本无限循环占用 CPU。
命令速用版
#!/bin/bash
while true; do
if ! pgrep -x "your_process_name" > /dev/null; then
echo "$(date): Process died, restarting..." >> /var/log/monitor.log
/path/to/start_command.sh
fi
sleep 10
done
为什么会这样
进程意外退出通常由代码错误、内存不足或依赖服务不可用导致。Shell 脚本充当外部看门狗,在进程主逻辑之外独立运行,确保即使主程序崩溃也能被重新拉起。
分步处理
第一步:编写监控脚本。将上述代码保存为 monitor.sh,修改进程名和启动命令,适用场景为自定义启动逻辑。
第二步:赋予执行权限。执行 chmod +x monitor.sh,操作动作完成后使用 ls -l 验证权限位包含 x。
第三步:后台运行脚本。使用 nohup ./monitor.sh & 或将其配置为 systemd 服务,验证结果为 ps -ef 能看到脚本进程存活。
风险边界:脚本自身崩溃会导致监控失效,建议由 systemd 管理该脚本。
怎么验证是否生效
查看日志文件确认重启记录。使用 kill -9 <pid> 手动杀死进程,观察日志是否新增重启条目且进程重新出现。
常见坑
重启频率过高会导致系统负载飙升,务必在循环中加入 sleep 等待,风险边界是 sleep 时间不宜短于 5 秒。日志文件未轮转可能占满磁盘,需配置 logrotate 或在脚本中限制日志大小,操作动作是定期检查/var/log 目录大小。
常见问题
用 Cron 定时任务代替 while 循环可以吗?
可以,但延迟较高。Cron 最小精度通常为分钟级,while 循环可实现秒级检测,根据业务容忍度选择。
Systemd 的 Restart=always 和脚本监控有什么区别?
Systemd 是内核级管理,更稳定且资源占用更低。脚本监控灵活性高但依赖 Shell 环境,适合 systemd 无法覆盖的场景。