Python自身无法异常后自重启,必须依赖外部工具;轻量用带信号处理的shell循环,可靠用Supervisor(需正确配置autostart/autorestart/startsecs/command等),切忌在Python内用os.execv()自重启。

Python脚本崩溃后怎么自动拉起来
靠 Python 自身做不到“异常后重启自己”——try/except 只能捕获并处理异常,一旦进程退出(比如未捕获的 SystemExit、KeyboardInterrupt、段错误、OOM kill),Python 就没了,没法再执行任何代码。必须靠外部进程管理工具兜底。
用 shell 脚本循环启动最轻量,但要注意信号和子进程继承
写个 while 循环看似简单,但直接 while true; do python main.py; done 会丢失 Ctrl+C 响应,且子进程可能变成僵尸。实际要用:
#!/bin/bash
trap '' SIGINT SIGTERM
while true; do
python main.py
exit_code=$?
# 避免因频繁崩溃导致无限重试(可选)
if [ $exit_code -ne 0 ]; then
sleep 1
fi
done关键点:
-
trap '' SIGINT SIGTERM阻止信号透传到子进程,否则 Ctrl+C 会同时杀掉 shell 和 Python - 检查
$?判断是否真崩溃,而非正常退出(比如脚本里写了sys.exit(0)) - 加
sleep防止闪退打满 CPU,也方便人工干预 - 不要用
nohup或&后台启动——那会让 while 失去对子进程的控制权
Supervisor 更可靠,但配置项容易配错
Supervisor 不是“只要装上就自动守护”,常见失效原因集中在三处:
立即学习“Python免费学习笔记(深入)”;
-
autostart=true和autorestart=true必须同时设为true,缺一不可 -
startsecs=1太小会导致 Supervisor 误判“启动成功”,建议设为3(进程需稳定运行 3 秒才算活) -
command必须写绝对路径,比如command=/usr/bin/python3 /opt/myapp/main.py,不能用~或相对路径 - Python 脚本里如果用了
os.chdir()或依赖当前工作目录,得在配置里显式加directory=/opt/myapp
另外:Supervisor 本身不处理内存泄漏或缓慢卡死,只看进程是否存活。若脚本假死但没退出,它不会重启。
要不要在 Python 里加 self-healing 逻辑
极少必要。有人在主循环里套 try/except Exception 然后 os.execv() 重启自身,但这有风险:
-
os.execv()会替换当前进程,但无法清理已分配的 C 扩展资源(如某些数据库连接池、共享内存) - 日志中会出现“重启链”,难以区分是首次启动还是第 7 次重试
- 若崩溃由全局状态污染引起(比如
sys.path被改乱),重启也救不回来
真正该做的,是在 Python 层把异常收口、打日志、暴露健康接口;把重启这件事,干净地交给 shell 或 Supervisor。
进程管理的边界要划清:Python 负责业务健壮性,外部工具负责进程存活性。混在一起,debug 时连 crash dump 都找不到源头。


















