linux运维脚本后台稳定运行且可捕获崩溃,需确保进程不随终端退出、错误有迹可循:用nohup+重定向+明确退出码组合;脚本内检查关键步骤并用trap清理资源;加锁文件或看门狗防假成功;日志结构化分离stdout/stderr,并用logger和logrotate管理。

Linux运维脚本在后台稳定运行且能捕获崩溃,关键在于两件事:一是确保进程不随终端退出而终止,二是让错误不被静默吞掉、有迹可循。光靠&或nohup还不够,必须配合输出重定向、退出码控制和信号处理。
用 nohup + 重定向 + 明确退出码
这是最常用也最可靠的组合,适用于大多数定时任务或长期守护类脚本:
-
nohup ./monitor.sh > monitor.log 2>&1 &—— 基础写法,把 stdout 和 stderr 合并写入日志 - 更推荐加时间戳和状态标记:
nohup ./backup.sh >> /var/log/backup.log 2>&1 && echo "[$(date)] SUCCESS" >> /var/log/backup.log || echo "[$(date)] FAILED" >> /var/log/backup.log & - 脚本内部必须检查关键步骤:比如文件生成后用
[ -s output.txt ] || exit 1,子命令用timeout 30s curl ... || exit 1 - 避免在异常处理中只
echo不exit 1——crontab 只认退出码,不是日志内容
在脚本里用 trap 捕获中断和崩溃
trap 不是防崩溃的,而是保证崩溃或中断时能清理资源、留下线索:
- 开头就注册:
trap 'cleanup' INT TERM HUP EXIT - 定义
cleanup()函数,里面做三件事:删临时目录、杀子进程、记录最后状态到日志(如echo "EXITED at $(date)" >> /var/log/script.log) - 所有要用的变量(比如
PID、TMPDIR)提前export,否则 trap 里拿不到 - 别忘了
EXIT——它兜底触发,不管是因为成功、失败还是被 kill,都能执行清理
加一层看门狗机制防“假成功”
有些脚本崩溃后没报错、也没退出(比如卡死在某个循环),日志停更但进程还在,系统误判为正常。这时需要外部验证:
- 脚本启动时写锁文件:
echo $$ > /tmp/myscript.pid - 结尾删除:
rm -f /tmp/myscript.pid - 另配一个检查脚本,每5分钟跑一次:
if [ -f /tmp/myscript.pid ] && [ $(($(date +%s) - $(stat -c %Y /tmp/myscript.pid))) -gt 600 ]; then echo "ALERT: myscript stuck!" | mail -s "Stuck Script" admin@example.com; kill $(cat /tmp/myscript.pid) 2>/dev/null; fi - 也可用
systemd-run --scope配合超时控制,适合新环境
日志与监控要分开管理
运维脚本的输出不能只靠nohup.out,得结构化:
- 标准输出(stdout)记录业务进度,比如“已同步1200条记录”
- 标准错误(stderr)只写真正异常,比如“连接数据库超时”,并确保它不被丢弃(
2>&1或单独重定向到.err) - 用
logger -t myscript把关键事件写进/var/log/messages,方便集中采集(如用 rsyslog 或 journalctl) - 定期轮转日志:
logrotate配置或脚本内用mv monitor.log monitor.log.$(date +%F).bak











