我写了一个Python脚本,检查一个特定的电子邮件地址,并将新的电子邮件传递给一个外部程序。如何让这个脚本全天候执行,比如在Linux中将其转换为守护进程或服务。我是否还需要一个在程序中永不结束的循环,或者可以通过多次重新执行代码来完成?
当前回答
使用你的系统提供的任何服务管理器——例如在Ubuntu下使用upstart。这将为您处理所有细节,如启动时启动,崩溃时重新启动等。
其他回答
你可以使用fork()将你的脚本从tty中分离出来,并让它继续运行,如下所示:
import os, sys
fpid = os.fork()
if fpid!=0:
# Running as daemon now. PID is fpid
sys.exit(0)
当然你还需要实现一个无限循环,比如
while 1:
do_your_check()
sleep(5)
希望这能让你开始。
如果你正在使用终端(ssh或其他东西),并且你想在退出终端后保持长时间的脚本工作,你可以尝试这样做:
屏幕
Apt-get安装屏幕
在里面创建一个虚拟终端(即abc): screen -dmS abc
现在我们连接到abc: screen -r abc
因此,现在我们可以运行python脚本:python keep_sending_mail .py
从现在开始,你可以直接关闭你的终端,但是,python脚本将继续运行而不是被关闭
因为这个keep_sending_mail .py的PID是虚拟屏幕的子进程,而不是 终端(ssh)
如果你想检查你的脚本运行状态,你可以再次使用screen -r abc
首先,仔细研究邮件别名。邮件别名将在邮件系统内完成此任务,而无需您在守护进程或服务或任何类似的东西上瞎忙活。
您可以编写一个简单的脚本,每次将邮件消息发送到特定邮箱时,sendmail都会执行该脚本。
参见http://www.feep.net/sendmail/tutorial/intro/aliases.html
如果您真的想编写一个不必要的复杂服务器,您可以这样做。
nohup python myscript.py &
这就够了。您的脚本只是循环和休眠。
import time
def do_the_work():
# one round of polling -- checking email, whatever.
while True:
time.sleep( 600 ) # 10 min.
try:
do_the_work()
except:
pass
我推荐这个解决方案。您需要继承和重写方法运行。
import sys
import os
from signal import SIGTERM
from abc import ABCMeta, abstractmethod
class Daemon(object):
__metaclass__ = ABCMeta
def __init__(self, pidfile):
self._pidfile = pidfile
@abstractmethod
def run(self):
pass
def _daemonize(self):
# decouple threads
pid = os.fork()
# stop first thread
if pid > 0:
sys.exit(0)
# write pid into a pidfile
with open(self._pidfile, 'w') as f:
print >> f, os.getpid()
def start(self):
# if daemon is started throw an error
if os.path.exists(self._pidfile):
raise Exception("Daemon is already started")
# create and switch to daemon thread
self._daemonize()
# run the body of the daemon
self.run()
def stop(self):
# check the pidfile existing
if os.path.exists(self._pidfile):
# read pid from the file
with open(self._pidfile, 'r') as f:
pid = int(f.read().strip())
# remove the pidfile
os.remove(self._pidfile)
# kill daemon
os.kill(pid, SIGTERM)
else:
raise Exception("Daemon is not started")
def restart(self):
self.stop()
self.start()
你应该使用python-daemon库,它会处理所有的事情。
从PyPI:库实现一个行为良好的Unix守护进程。
推荐文章
- 如何在交互式Python中查看整个命令历史?
- 如何显示有两个小数点后的浮点数?
- 如何用OpenCV2.0和Python2.6调整图像大小
- 在每个列表元素上调用int()函数?
- Linux: kill后台任务
- 当使用代码存储库时,如何引用资源的相对路径
- 如何修改Linux系统中打开文件的数量限制?
- 如何在Flask-SQLAlchemy中按id删除记录
- 在Python中插入列表的第一个位置
- Python Pandas只合并某些列
- 如何在一行中连接两个集而不使用“|”
- 从字符串中移除前缀
- 代码结束时发出警报
- 如何在Python中按字母顺序排序字符串中的字母
- 在matplotlib中将y轴标签添加到次要y轴