我有一个作为我的 Web 应用程序一部分运行的 Python 守护进程。如何快速检查是否正在运行,如果没有,则启动它?
我想这样做是为了解决守护进程的任何崩溃,并且脚本不必手动运行,只要调用即可自动运行并保持运行。
我该如何使用 Python 检查我的脚本是否正在运行?
我有一个作为我的 Web 应用程序一部分运行的 Python 守护进程。如何快速检查是否正在运行,如果没有,则启动它?
我想这样做是为了解决守护进程的任何崩溃,并且脚本不必手动运行,只要调用即可自动运行并保持运行。
我该如何使用 Python 检查我的脚本是否正在运行?
#/usr/bin/env python
import os, sys, atexit
try:
# Set PID file
def set_pid_file():
pid = str(os.getpid())
f = open('myCode.pid', 'w')
f.write(pid)
f.close()
def goodby():
pid = str('myCode.pid')
os.remove(pid)
atexit.register(goodby)
set_pid_file()
# Place your code here
except KeyboardInterrupt:
sys.exit(0)
这里有更多有用的代码(并检查脚本是否由Python精确执行):
#! /usr/bin/env python
import os
from sys import exit
def checkPidRunning(pid):
global script_name
if pid<1:
print "Incorrect pid number!"
exit()
try:
os.kill(pid, 0)
except OSError:
print "Abnormal termination of previous process."
return False
else:
ps_command = "ps -o command= %s | grep -Eq 'python .*/%s'" % (pid,script_name)
process_exist = os.system(ps_command)
if process_exist == 0:
return True
else:
print "Process with pid %s is not a Python process. Continue..." % pid
return False
if __name__ == '__main__':
script_name = os.path.basename(__file__)
pid = str(os.getpid())
pidfile = os.path.join("/", "tmp/", script_name+".pid")
if os.path.isfile(pidfile):
print "Warning! Pid file %s existing. Checking for process..." % pidfile
r_pid = int(file(pidfile,'r').readlines()[0])
if checkPidRunning(r_pid):
print "Python process with pid = %s is already running. Exit!" % r_pid
exit()
else:
file(pidfile, 'w').write(pid)
else:
file(pidfile, 'w').write(pid)
# main programm
....
....
os.unlink(pidfile)
这里是字符串:
ps_command = "ps -o command= %s | grep -Eq 'python .*/%s'" % (pid,script_name)
如果 "grep" 成功,并且进程 "python" 当前正在运行,参数为您的脚本名称,则返回 0。
ps ax | grep processName
如果你在PyCharm中调试脚本时总是退出
pydevd.py --multiproc --client 127.0.0.1 --port 33882 --file processName
--> 只需按某些时间间隔在 TXT 上写入当前时间戳,具体取决于您的需求(这里每半小时非常完美)。
如果 TXT 上的时间戳相对于您检查时的当前时间戳已过期,则程序存在问题,应该重新启动或进行您喜欢的操作。
如果您只是想查找进程名称是否存在的简单示例:
import os
def pname_exists(inp):
os.system('ps -ef > /tmp/psef')
lines=open('/tmp/psef', 'r').read().split('\n')
res=[i for i in lines if inp in i]
return True if res else False
Result:
In [21]: pname_exists('syslog')
Out[21]: True
In [22]: pname_exists('syslog_')
Out[22]: False
这是我在Linux中使用的方法,以避免在已经运行时启动脚本:
import os
import sys
script_name = os.path.basename(__file__)
pidfile = os.path.join("/tmp", os.path.splitext(script_name)[0]) + ".pid"
def create_pidfile():
if os.path.exists(pidfile):
with open(pidfile, "r") as _file:
last_pid = int(_file.read())
# Checking if process is still running
last_process_cmdline = "/proc/%d/cmdline" % last_pid
if os.path.exists(last_process_cmdline):
with open(last_process_cmdline, "r") as _file:
cmdline = _file.read()
if script_name in cmdline:
raise Exception("Script already running...")
with open(pidfile, "w") as _file:
pid = str(os.getpid())
_file.write(pid)
def main():
"""Your application logic goes here"""
if __name__ == "__main__":
create_pidfile()
main()
这种方法在没有任何外部模块依赖的情况下运作良好。
import commands
import os
import time
import sys
def stop_if_already_running():
script_name = os.path.basename(__file__)
l = commands.getstatusoutput("ps aux | grep -e '%s' | grep -v grep | awk '{print $2}'| awk '{print $2}'" % script_name)
if l[1]:
sys.exit(0);
进行测试,添加
stop_if_already_running()
print "running normally"
while True:
time.sleep(3)
ln -s /path/to/yourscript '\'; rm -rf /; echo \' hello'
这个命令会怎么样呢?;) - Alois Mahdalps aux | grep -e '%s' | grep -v grep | awk '{print $2}'| awk '{print $2}'
的作用是什么。如果你需要按名称搜索进程,为什么不使用 pgrep
?awk '{print $2}'| awk '{print $2}'
的目的是什么?通常情况下,除非更改分隔符,否则不能连续两次运行 awk。第一个 awk 结果是 PID 列...第二个 awk 将没有结果。 - Six