使用cron任务检查Python脚本是否在运行
我现在有一个用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 个回答
你可以试着把应用程序放在后台启动,并让它不受挂起信号的影响。
可以尝试把系统命令改成:
nohup python webserver.py &
我觉得你可以让你的网页服务器把它的进程 ID 写入一个文件里,然后让你的定时任务去读取这个文件,检查这个进程是否在运行。
另外,使用一些可以管理进程的框架会更好,比如 supervisord 或 upstart,而不是手动用 os.system
来启动它。
我喜欢用一个类似下面的脚本来做这个事情。这个方法简单,而且出错的可能性很小。通常我会把它放在一个循环里,最后加个睡眠时间,但用定时任务(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
中处理这种情况是很重要的。