我写了一个Python脚本,检查一个特定的电子邮件地址,并将新的电子邮件传递给一个外部程序。如何让这个脚本全天候执行,比如在Linux中将其转换为守护进程或服务。我是否还需要一个在程序中永不结束的循环,或者可以通过多次重新执行代码来完成?
当前回答
您还可以使用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。
其他回答
我推荐这个解决方案。您需要继承和重写方法运行。
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()
使用你的系统提供的任何服务管理器——例如在Ubuntu下使用upstart。这将为您处理所有细节,如启动时启动,崩溃时重新启动等。
Ubuntu有一个非常简单的方法来管理服务。 对于python来说,不同之处在于所有依赖项(包)都必须在运行主文件的同一目录中。
我只是设法创建了这样一个服务,为我的客户提供天气信息。 步骤:
Create your python application project as you normally do. Install all dependencies locally like: sudo pip3 install package_name -t . Create your command line variables and handle them in code (if you need any) Create the service file. Something (minimalist) like: [Unit] Description=1Droid Weather meddleware provider [Service] Restart=always User=root WorkingDirectory=/home/ubuntu/weather ExecStart=/usr/bin/python3 /home/ubuntu/weather/main.py httpport=9570 provider=OWMap [Install] WantedBy=multi-user.target Save the file as myweather.service (for example) Make sure that your app runs if started in the current directory python3 main.py httpport=9570 provider=OWMap The service file produced above and named myweather.service (important to have the extension .service) will be treated by the system as the name of your service. That is the name that you will use to interact with your service. Copy the service file: sudo cp myweather.service /lib/systemd/system/myweather.service Refresh demon registry: sudo systemctl daemon-reload Stop the service (if it was running) sudo service myweather stop Start the service: sudo service myweather start Check the status (log file with where your print statements go): tail -f /var/log/syslog Or check the status with: sudo service myweather status Back to the start with another iteration if needed
此服务现在正在运行,即使您退出也不会受到影响。 如果主机关闭并重新启动,则此服务将重新启动…
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守护进程好得多。
如果你正在使用终端(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
推荐文章
- 使用Pandas groupby连接来自几行的字符串
- Pandas:给定列的数据帧行之和
- 如何避免在为Python项目构建Docker映像时重新安装包?
- 如何激活蟒蛇环境
- 省略[…]意思是在一个列表里?
- 为什么我得到“'str'对象没有属性'读取'”当尝试使用' json。载入字符串?
- 不区分大小写的列表排序,没有降低结果?
- 有效地测试Linux上的端口是否打开?
- 排序后的语法(key=lambda:…)
- 在烧瓶中返回HTTP状态代码201
- 如何从另一个文件A中删除文件B中出现的行?
- 使用python创建一个简单的XML文件
- APT命令行界面式的yes/no输入?
- 如何打印出状态栏和百分比?
- 在Python中获取大文件的MD5哈希值