我写了一个Python脚本,检查一个特定的电子邮件地址,并将新的电子邮件传递给一个外部程序。如何让这个脚本全天候执行,比如在Linux中将其转换为守护进程或服务。我是否还需要一个在程序中永不结束的循环,或者可以通过多次重新执行代码来完成?
当前回答
假设您真的希望您的循环作为后台服务全天候运行
对于一个不需要向代码中注入库的解决方案,你可以简单地创建一个服务模板,因为你使用的是linux:
[Unit]
Description = <Your service description here>
After = network.target # Assuming you want to start after network interfaces are made available
[Service]
Type = simple
ExecStart = python <Path of the script you want to run>
User = # User to run the script as
Group = # Group to run the script as
Restart = on-failure # Restart when there are errors
SyslogIdentifier = <Name of logs for the service>
RestartSec = 5
TimeoutStartSec = infinity
[Install]
WantedBy = multi-user.target # Make it accessible to other users
将该文件放在您的守护进程服务文件夹(通常是/etc/systemd/system/)中,*. .使用以下systemctl命令安装它(可能需要sudo权限):
systemctl enable <service file name without .service extension>
systemctl daemon-reload
systemctl start <service file name without .service extension>
然后你可以使用命令检查你的服务是否在运行:
systemctl | grep running
其他回答
要创建一些像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
首先,仔细研究邮件别名。邮件别名将在邮件系统内完成此任务,而无需您在守护进程或服务或任何类似的东西上瞎忙活。
您可以编写一个简单的脚本,每次将邮件消息发送到特定邮箱时,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
如果你正在使用终端(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
cron is clearly a great choice for many purposes. However it doesn't create a service or daemon as you requested in the OP. cron just runs jobs periodically (meaning the job starts and stops), and no more often than once / minute. There are issues with cron -- for example, if a prior instance of your script is still running the next time the cron schedule comes around and launches a new instance, is that OK? cron doesn't handle dependencies; it just tries to start a job when the schedule says to.
如果您发现确实需要一个守护进程(一个永不停止运行的进程),请查看一下监控器。它提供了一种简单的方法来包装普通的、非守护进程化的脚本或程序,并使其像守护进程一样运行。这比创建本地Python守护进程好得多。
你可以使用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)
希望这能让你开始。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用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命令的全部输出