Python 脚本作为 linux 服务/守护进程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4705564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python script as linux service/daemon
提问by tauran
Hallo,
你好,
I'm trying to let a python script run as service (daemon) on (ubuntu) linux.
我试图让 python 脚本作为服务(守护进程)在(ubuntu)linux 上运行。
On the web there exist several solutions like:
在网络上有几种解决方案,例如:
http://pypi.python.org/pypi/python-daemon/
http://pypi.python.org/pypi/python-daemon/
A well-behaved Unix daemon process is tricky to get right, but the required steps are much the same for every daemon program. A DaemonContext instance holds the behaviour and configured process environment for the program; use the instance as a context manager to enter a daemon state.
一个行为良好的 Unix 守护进程很难做到正确,但每个守护程序所需的步骤都大同小异。DaemonContext 实例保存程序的行为和配置的进程环境;使用实例作为上下文管理器进入守护进程状态。
http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
However as I want to integrate my python script specifically with ubuntu linux my solution is a combination with an init.d script
但是,因为我想将我的 python 脚本专门与 ubuntu linux 集成,所以我的解决方案是与 init.d 脚本的组合
#!/bin/bash
WORK_DIR="/var/lib/foo"
DAEMON="/usr/bin/python"
ARGS="/opt/foo/linux_service.py"
PIDFILE="/var/run/foo.pid"
USER="foo"
case "" in
start)
echo "Starting server"
mkdir -p "$WORK_DIR"
/sbin/start-stop-daemon --start --pidfile $PIDFILE \
--user $USER --group $USER \
-b --make-pidfile \
--chuid $USER \
--exec $DAEMON $ARGS
;;
stop)
echo "Stopping server"
/sbin/start-stop-daemon --stop --pidfile $PIDFILE --verbose
;;
*)
echo "Usage: /etc/init.d/$USER {start|stop}"
exit 1
;;
esac
exit 0
and in python:
在 python 中:
import signal
import time
import multiprocessing
stop_event = multiprocessing.Event()
def stop(signum, frame):
stop_event.set()
signal.signal(signal.SIGTERM, stop)
if __name__ == '__main__':
while not stop_event.is_set():
time.sleep(3)
My question now is if this approach is correct. Do I have to handle any additional signals? Will it be a "well-behaved Unix daemon process"?
我现在的问题是这种方法是否正确。我必须处理任何额外的信号吗?它会是一个“表现良好的 Unix 守护进程”吗?
采纳答案by rlotun
Assuming your daemon has some way of continually running (some event loop, twisted, whatever), you can try to use upstart
.
假设你的守护进程有某种持续运行的方式(一些事件循环、扭曲等等),你可以尝试使用upstart
.
Here's an example upstart config for a hypothetical Python service:
这是一个假设的 Python 服务的示例 upstart 配置:
description "My service"
author "Some Dude <[email protected]>"
start on runlevel [234]
stop on runlevel [0156]
chdir /some/dir
exec /some/dir/script.py
respawn
If you save this as script.conf to /etc/init
you simple do a one-time
如果你把它保存为 script.conf 给/etc/init
你简单的做一次
$ sudo initctl reload-configuration
$ sudo start script
You can stop it with stop script
. What the above upstart conf says is to start this service on reboots and also restart it if it dies.
你可以用 来阻止它stop script
。上面的 upstart conf 说的是在重新启动时启动这个服务,如果它死了也重新启动它。
As for signal handling - your process should naturally respond to SIGTERM
. By default this should be handled unless you've specifically installed your own signal handler.
至于信号处理 - 您的进程应该自然地响应SIGTERM
. 默认情况下,除非您专门安装了自己的信号处理程序,否则应处理此问题。
回答by Ross R
Rloton's answer is good. Here is a light refinement, just because I spent a ton of time debugging. And I need to do a new answer so I can format properly.
罗顿的回答很好。这是一个轻微的改进,只是因为我花了大量时间调试。我需要做一个新的答案,这样我才能正确地格式化。
A couple other points that took me forever to debug:
其他几点让我永远调试:
- When it fails, first check /var/log/upstart/.log
- If your script implements a daemon with python-daemon, you do NOT use the 'expect daemon' stanza. Having no 'expect' works. I don't know why. (If anyone knows why - please post!)
- Also, keep checking "initctl status script" to make sure you are up (start/running). (and do a reload when you update your conf file)
- 当它失败时,首先检查/var/log/upstart/.log
- 如果您的脚本使用python-daemon实现守护程序,则不要使用“expect daemon”节。没有“期望”的作品。我不知道为什么。(如果有人知道为什么 - 请张贴!)
- 此外,请继续检查“initctl 状态脚本”以确保您已启动(启动/运行)。(并在更新 conf 文件时重新加载)
Here is my version:
这是我的版本:
description "My service"
author "Some Dude <[email protected]>"
env PYTHON_HOME=/<pathtovirtualenv>
env PATH=$PYTHON_HOME:$PATH
start on runlevel [2345]
stop on runlevel [016]
chdir <directory>
# NO expect stanza if your script uses python-daemon
exec $PYTHON_HOME/bin/python script.py
# Only turn on respawn after you've debugged getting it to start and stop properly
respawn