【问题标题】:How to auto-restart a python script on fail?如何在失败时自动重启python脚本?
【发布时间】:2011-02-12 10:57:00
【问题描述】:

这篇文章描述了如何在 BASH 脚本中保持子进程处于活动状态:

How do I write a bash script to restart a process if it dies?

这非常适合调用另一个 BASH 脚本。

但是,我尝试在子进程是 Python 脚本的情况下执行类似的操作,daemon.py 会创建一个在后台运行的分叉子进程:

#!/bin/bash

PYTHON=/usr/bin/python2.6

function myprocess {


$PYTHON daemon.py start

}
NOW=$(date +"%b-%d-%y")

until myprocess; do
     echo "$NOW Prog crashed. Restarting..." >> error.txt
     sleep 1
done

现在行为完全不同了。似乎 python 脚本不再是 bash 脚本的子脚本,但似乎已经“接管”了 BASH 脚本 PID - 所以被调用的脚本周围不再有 BASH 包装器......为什么?

【问题讨论】:

  • 了解 daemon.py 中的内容会有所帮助,但从名称上我猜它会执行“exec”或任何与 python 等价的东西将自己置于后台。
  • 真的应该把标题从“Python”改成“daemonized”。

标签: python bash process daemon pid


【解决方案1】:

守护进程双叉,作为守护进程自身的关键点——因此父进程拥有的 PID 没有任何价值(在子进程启动后它很快就消失了)。

因此,守护进程应该将其 PID 写入“众所周知的位置”的文件中,按照惯例,父进程知道从哪里读取它;使用这种(传统)方法,如果父进程想要​​充当重启看门狗,可以简单地从已知位置读取守护进程的 PID,并定期检查守护进程是否仍然存在,并在需要时重新启动它。

当然,它在执行时需要小心(“陈旧”的 PID 会在“众所周知的位置”文件中停留一段时间,父进程必须考虑到这一点),并且存在可能的变体(守护进程可以发出“心跳”,以便父进程不仅可以检测到死的守护进程,还可以检测到“永远卡住”的守护进程,例如由于死锁,因为它们停止发出“心跳”[[通过 UDP 广播等]] -- 等等等等),但这是一般的想法。

【讨论】:

    【解决方案2】:

    似乎行为完全不同,因为在这里您的“daemon.py”作为守护进程在后台启动。

    在另一个链接中,您指出被调查的进程不是守护进程,它不会在后台启动。启动器只是永远等待子进程停止。

    有几种方法可以克服这个问题。经典的一种是@Alex 解释的方式,在常规位置使用一些 pid 文件。

    另一种方法是在您正在运行的守护程序中构建看门狗并守护看门狗...这将模拟一个不会随机中断的正确进程(不应该发生的事情)...

    【讨论】:

      【解决方案3】:

      您应该查看 Python 增强提案 3143 (PEP) here。在其中,Ben 建议在 python 标准库中包含一个守护程序库。他阅读了很多关于守护进程的非常好的信息,并且很容易阅读。参考实现是here

      【讨论】:

      • 感谢保罗的参考。看起来很有用。
      【解决方案4】:

      使用“https://github.com/ut0mt8/simple-ha”。

      简单哈

      厌倦了keepalived、corosync、起搏器、心跳或其他什么?这里有一个简单的守护进程来确保两台主机之间的心跳。一个是活动的,另一个是备份,改变状态时启动脚本。简单的实现,KISS。生产就绪(至少它对我有用:)

      生活太容易了!

      【讨论】:

      • 虽然理论上这可以回答这个问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
      猜你喜欢
      • 1970-01-01
      • 2018-05-09
      • 2018-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-17
      • 1970-01-01
      • 2020-02-04
      相关资源
      最近更新 更多