如果 Python 脚本被杀死或死亡,如何自动重新启动它

ars*_*nal 39 shell bash cron python

我在我的 Ubuntu 机器(12.04)的后台运行我的 Python 脚本,就像这样 -

nohup python testing.py > test.out &
Run Code Online (Sandbox Code Playgroud)

现在,在某个阶段,我的上述Python script可能会因任何原因而死亡。

所以我想cron agent在 bash shell 脚本中有某种形式,如果它因任何原因被杀死,它可以自动重新启动我上面的 Python 脚本。

这是可能的吗?如果是,那么解决此类问题的最佳方法是什么?

更新:

创建这样的testing.conf文件后-

chdir /tekooz
exec python testing.py
respawn
Run Code Online (Sandbox Code Playgroud)

我在 sudo 命令下运行以启动它,但我看不到使用 ps ax 运行的进程?

root@bx13:/bezook# sudo start testing
testing start/running, process 27794
root@bx13:/bezook# ps ax | grep testing.py
27806 pts/3    S+     0:00 grep --color=auto testing.py
Run Code Online (Sandbox Code Playgroud)

知道为什么 px ax 没有显示任何内容吗?以及如何检查我的程序是否正在运行?

这是我的python脚本-

#!/usr/bin/python
while True:
    print "Hello World"
    time.sleep(5)
Run Code Online (Sandbox Code Playgroud)

Zel*_*lda 27

在 Ubuntu 上(直到 14.04、16.04 和更高版本使用 systemd)可以使用 upstart 来做到这一点,比 cron 作业更好。您放入配置设置/etc/init并确保指定respawn

它可能是一个最小的文件/etc/init/testing.conf(编辑为root):

chdir /your/base/directory
exec python testing.py
respawn
Run Code Online (Sandbox Code Playgroud)

你可以测试/your/base/directory/testing.py

from __future__ import print_function

import time

with open('/var/tmp/testing.log', 'a') as fp:
    print(time.time(), 'done', file=fp)
    time.sleep(3)
Run Code Online (Sandbox Code Playgroud)

并开始:

sudo start testing
Run Code Online (Sandbox Code Playgroud)

并遵循(在另一个窗口中)发生的情况:

tail -f /var/tmp/testing.log
Run Code Online (Sandbox Code Playgroud)

并停止:

sudo stop testing
Run Code Online (Sandbox Code Playgroud)

您还可以添加[start on][2]在系统启动时启动命令。


ter*_*don 23

您还可以采用更面向外壳的方法。有你cron看看你的脚本,然后重新启动它,如果它死了。

  1. 通过运行创建一个新的 crontab crontab -e。这将打开您最喜欢的文本编辑器的窗口。

  2. 将此行添加到刚刚打开的文件中

    */5 * * * * pgrep -f testing.py || nohup python /home/you/scripts/testing.py > test.out
    
    Run Code Online (Sandbox Code Playgroud)
  3. 保存文件并退出编辑器。

您刚刚创建了一个新的crontab,它将每 5 分钟运行一次并启动您的脚本,除非它已经在运行。见这里的一个不错的小教程cron。Ubuntu官方文档上cron位置

正在运行的实际命令是pgrep为命令行中给出的字符串搜索正在运行的进程。pgrep foo将搜索名为的程序foo并返回其进程标识符pgrep -f使其搜索用于启动程序的整个命令行,而不仅仅是程序名称(很有用,因为这是一个 python 脚本)。

||符号的意思是“如果上一个命令失败,则执行此操作”。因此,如果您的脚本没有运行,pgrep它将失败,因为它什么也找不到,您的脚本将被启动。


K3-*_*rnc 8

您不应该真正将其用于生产,但您可以:

#!/bin/sh

while true; do
  nohup python testing.py >> test.out
done &
Run Code Online (Sandbox Code Playgroud)

如果出于任何原因,python 进程退出,shell 循环将继续并重新启动它,.out根据需要附加到文件中。几乎没有开销,设置时间也很短。


Jim*_*nis 6

在 UNIX/Linux 下有多种方法可以监视和重新生成进程。最古老的条目之一是 /etc/inittab 中的“respawn”条目……如果您使用的是旧的 SysV init 系统。另一种方法是使用 DJ Bernstein 的daemontools包中的主管守护程序。其他选项是使用 Ubuntu upstart ... 或systemd或其他中的功能。

但是您可以查看替代方法 initPardus的 Python 代码特别是mudur守护进程。

如果您决定使用 cron 作业(和 PID 文件处理),请考虑阅读此PEP 3143并可能使用其参考实现。

正如我在其他评论中提到的,强大的 PID 文件处理很棘手。它很容易发生竞争和极端情况。如果您的 PID 文件有可能最终出现在 NFS 或其他网络文件系统上(某些原子性保证您在适当的本地UNIX/Linux 文件系统上获得文件处理语义,则在某些 NFS 版本和实现上消失,这将变得更加棘手,例如)。此外,UNIX 下文件锁定的语义可能很棘手。(例如,在您的目标操作系统中,当持有它的进程被 SIGKILL 杀死时,flockorfcntl锁是否会立即释放?)。


Ant*_*hon 6

您可以让测试程序使用命令行选项重定向输出,然后使用简单的 python 脚本无限期地重新启动程序:

import subprocess

while True:
    try:
        print subprocess.check_output(['python', 'testing.py'])
    except KeyboardInterrupt:
        break
Run Code Online (Sandbox Code Playgroud)

你可以把这个程序放在后台,一旦你想停止,就把它拉到前台并杀死它。