我写了一个Python脚本,检查一个特定的电子邮件地址,并将新的电子邮件传递给一个外部程序。如何让这个脚本全天候执行,比如在Linux中将其转换为守护进程或服务。我是否还需要一个在程序中永不结束的循环,或者可以通过多次重新执行代码来完成?
当前回答
一个简单且受支持的版本是Daemonize。
从Python包索引(PyPI)安装它:
$ pip install daemonize
然后用like:
...
import os, sys
from daemonize import Daemonize
...
def main()
# your code here
if __name__ == '__main__':
myname=os.path.basename(sys.argv[0])
pidfile='/tmp/%s' % myname # any name
daemon = Daemonize(app=myname,pid=pidfile, action=main)
daemon.start()
其他回答
要创建一些像service一样运行的东西,你可以使用这个东西:
你必须做的第一件事是安装水泥框架: 水泥框架是一个CLI框架,您可以在其上部署应用程序。
app命令行界面:
interface.py
from cement.core.foundation import CementApp
from cement.core.controller import CementBaseController, expose
from YourApp import yourApp
class Meta:
label = 'base'
description = "your application description"
arguments = [
(['-r' , '--run'],
dict(action='store_true', help='Run your application')),
(['-v', '--version'],
dict(action='version', version="Your app version")),
]
(['-s', '--stop'],
dict(action='store_true', help="Stop your application")),
]
@expose(hide=True)
def default(self):
if self.app.pargs.run:
#Start to running the your app from there !
YourApp.yourApp()
if self.app.pargs.stop:
#Stop your application
YourApp.yourApp.stop()
class App(CementApp):
class Meta:
label = 'Uptime'
base_controller = 'base'
handlers = [MyBaseController]
with App() as app:
app.run()
YourApp.py类:
import threading
class yourApp:
def __init__:
self.loger = log_exception.exception_loger()
thread = threading.Thread(target=self.start, args=())
thread.daemon = True
thread.start()
def start(self):
#Do every thing you want
pass
def stop(self):
#Do some things to stop your application
请记住,你的应用程序必须运行在一个线程作为守护进程
要运行应用程序,只需在命令行中这样做
Python interface.py——help
您还可以使用shell脚本使python脚本作为服务运行。首先创建一个shell脚本,像这样运行python脚本(scriptname任意名称)
#!/bin/sh
script='/home/.. full path to script'
/usr/bin/python $script &
现在在/etc/init.d/scriptname中创建一个文件
#! /bin/sh
PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/home/.. path to shell script scriptname created to run python script
PIDFILE=/var/run/scriptname.pid
test -x $DAEMON || exit 0
. /lib/lsb/init-functions
case "$1" in
start)
log_daemon_msg "Starting feedparser"
start_daemon -p $PIDFILE $DAEMON
log_end_msg $?
;;
stop)
log_daemon_msg "Stopping feedparser"
killproc -p $PIDFILE $DAEMON
PID=`ps x |grep feed | head -1 | awk '{print $1}'`
kill -9 $PID
log_end_msg $?
;;
force-reload|restart)
$0 stop
$0 start
;;
status)
status_of_proc -p $PIDFILE $DAEMON atd && exit 0 || exit $?
;;
*)
echo "Usage: /etc/init.d/atd {start|stop|restart|force-reload|status}"
exit 1
;;
esac
exit 0
现在可以使用/etc/init.命令启动和停止python脚本D /scriptname start or stop。
你可以使用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
你有两个选择。
Make a proper cron job that calls your script. Cron is a common name for a GNU/Linux daemon that periodically launches scripts according to a schedule you set. You add your script into a crontab or place a symlink to it into a special directory and the daemon handles the job of launching it in the background. You can read more at Wikipedia. There is a variety of different cron daemons, but your GNU/Linux system should have it already installed. Use some kind of python approach (a library, for example) for your script to be able to daemonize itself. Yes, it will require a simple event loop (where your events are timer triggering, possibly, provided by sleep function).
我不建议你选择2。,因为您实际上是在重复cron功能。Linux系统范例是让多个简单工具交互并解决您的问题。除非有其他原因需要创建守护进程(除了定期触发之外),否则选择其他方法。
此外,如果你使用daemonize进行循环并且发生了崩溃,那么没有人会在那之后检查邮件(正如Ivan Nevostruev在回答的评论中指出的那样)。而如果脚本作为cron作业添加,它将再次触发。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 在Bash中检查变量是否存在于列表中
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 查看PS命令的全部输出