我写了一个Python脚本,检查一个特定的电子邮件地址,并将新的电子邮件传递给一个外部程序。如何让这个脚本全天候执行,比如在Linux中将其转换为守护进程或服务。我是否还需要一个在程序中永不结束的循环,或者可以通过多次重新执行代码来完成?


当前回答

要创建一些像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

您可以在脚本中或像这样在另一个脚本中作为子进程运行进程

subprocess.Popen(arguments, close_fds=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL)

或者使用现成的工具

https://github.com/megashchik/d-handler

你应该使用python-daemon库,它会处理所有的事情。

从PyPI:库实现一个行为良好的Unix守护进程。

您还可以使用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。

要创建一些像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