使用cron任务检查Python脚本是否在运行

1 投票
3 回答
4500 浏览
提问于 2025-04-17 12:44

我现在有一个用Python写的网页服务器应用程序在运行,我想用一个Python脚本来做定时任务,检查这个应用程序是否在运行,如果没有运行就启动它。

我有以下的代码:

import os

string = os.popen('ps aux')
n = 0
for line in string.readlines():
  if "python webserver.py" in line:
    n+=1
if n < 1:
  os.system('python webserver.py')

现在这个脚本已经执行了应用程序。但是我想要的是,脚本启动应用程序后就退出,让应用程序继续运行。有没有什么方法可以做到这一点?谢谢!

3 个回答

0

你可以试着把应用程序放在后台启动,并让它不受挂起信号的影响。

可以尝试把系统命令改成:

nohup python webserver.py &
2

我觉得你可以让你的网页服务器把它的进程 ID 写入一个文件里,然后让你的定时任务去读取这个文件,检查这个进程是否在运行。

另外,使用一些可以管理进程的框架会更好,比如 supervisord 或 upstart,而不是手动用 os.system 来启动它。

2

我喜欢用一个类似下面的脚本来做这个事情。这个方法简单,而且出错的可能性很小。通常我会把它放在一个循环里,最后加个睡眠时间,但用定时任务(cron)也可以。

if [ -x myproc.pid ] ; then
    pid=`cat myproc.pid`
else
    pid=1
fi
kill -0 $pid #check if process is still running

如你所见,这个脚本要求你的程序在启动时把它的进程ID(PID)写入一个文件。这样可以避免用命令查看进程时出现的问题,因为要写一个总能适用的正则表达式很麻烦,尤其是未来可能会有新的进程名出现。用PID文件就绝对没问题。

kill -0是一个不太为人所知的方法,用来检查一个进程是否在运行,比起查看/proc目录要简单得多。那行pid=1是因为检查者不是超级用户(root),所以如果你不能向进程发送信号,kill检查就会失败。这是为了处理我的程序第一次在这个服务器上运行的情况。需要注意的是,检查脚本不能以root身份运行(这通常是个好习惯),而是要以运行你要检查的进程的同一个用户身份运行。

如果你真的想用Python来做这个,os模块可以访问PID,并且有一个kill方法。不过,它不会返回一个shell的退出代码,而是会抛出OSError异常,你可以在try - catch块中处理这个异常。用信号0来检测进程是否存在的原理是一样的,但有可能你的进程已经结束,另一个进程现在使用了相同的PID,所以在try - catch中处理这种情况是很重要的。

撰写回答