如何知道正在运行的脚本是否停止?

4

我对编程还比较新手,大部分是自学的,如果这个问题有点初级,请见谅。

我有一个python脚本,可以运行很长时间(例如每几秒钟下载一次页面,数天为一周期)。这是应用程序监控脚本。

偶尔会出现一些故障,需要重新启动。我已经让这种情况尽可能地少发生,但它仍然会每隔几天发生一次。如果我没有注意到它被杀死了,那就可能是坏消息。

现在它在VPS上的screen会话中运行。

请问有人可以指点我如何知道脚本何时停止运行/并使其自动重新启动吗?

这是否需要在Bash中编写?还是其他东西?我以前从未做过这样的事情,不知道从哪里开始或查找信息。


你应该在代码中执行这个操作。它为什么会挂掉? - Blender
1
你可能也想加入一个监控钩子 - 让它每隔几秒钟触发一次临时文件或生成一些日志输出; 然后你就可以轻松地设置一个单独的看门狗(甚至在不同的主机上)。 - tripleee
4个回答

4
您应该将程序设为守护进程。
Efficient Python Daemon所述,您可以安装并使用python-daemon来实现PEP 3143的规范,即“标准守护进程库”。
创建一个名为mydaemon.py的文件,并添加以下内容:
#!/usr/bin/env python

import daemon
import time
import logging

def do_something():
    name = 'mydaemon'
    logger = logging.getLogger(name)
    handler = logging.FileHandler('/tmp/%s.log' % (name))
    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler) 
    logger.setLevel(logging.WARNING)

    while True:
        try:
            time.sleep(5)
            with open("/tmp/file-does-not-exist", "r") as f:
                f.write("The time is now " + time.ctime())
        except Exception, ex:
            logger.error(ex)

def run():
    with daemon.DaemonContext():
        do_something()

if __name__ == "__main__":
    run()

要实际运行它,请使用:

python mydaemon.py

这会在DaemonContext中生成do_something(),然后脚本mydaemon.py将退出。您可以使用pgrep -fl mydaemon.py命令查看正在运行的守护进程。这个简短的示例将简单地将错误记录到/tmp/mydaemon.log的日志文件中。您需要手动杀死守护程序,否则它将无限期运行。

要运行自己的程序,只需用自己的代码替换try块的内容即可。


谢谢,这非常清晰易懂。我之前完全不知道守护进程的概念。 - some1

4
您可以尝试使用supervisord,它是一个控制守护进程的工具。

3
我相信编写一个包装bash脚本,在循环中执行python脚本,可以解决问题。
while true; do
    # Execute python script here
    echo "Web app monitoring script disrupted ... Restarting script."
done

希望这能帮到您。

1
最好将脚本daemonize并在其中适当处理异常(至少要将异常记录下来)。 - aculich

2

这取决于您想要防范的故障类型。如果只是脚本崩溃,最简单的方法是在主函数中使用try/except语句:

import logging as log

while True:
    try:
        main()
    except:
        log.exception("main() crashed")

如果某些东西正在杀死Python进程,最简单的方法可能是在shell循环中运行它:

while sleep 1; do python checker.py; done

如果程序因为机器崩溃而崩溃......那么,谁来监督守卫者呢?

然而,直接回答您的问题:检查程序是否在 shell 中运行的绝对最简单的方法是 grep ps 命令的输出:

ps | grep "python checker.py" 2>&1 > /dev/null
running=$?

当然,这并非绝对可靠,但通常足够好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接