Hallo,
Ich versuche, ein python script als service (daemon) unter (ubuntu) linux laufen zu lassen.
Im Web gibt es verschiedene Lösungen wie:
http://pypi.python.org/pypi/python-daemon/
Ein ordentlicher Unix-Daemon-Prozess ist schwierig, aber die erforderlichen Schritte sind für jedes Daemon-Programm gleich. Eine DaemonContext-Instanz enthält das Verhalten und die konfigurierte Prozessumgebung für das Programm. Verwenden Sie die Instanz als Kontextmanager, um einen Dämonstatus einzugeben.
http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
Da ich mein python -Skript jedoch speziell in Ubuntu Linux integrieren möchte, ist meine Lösung eine Kombination mit einem init.d-Skript
#!/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 "$1" 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
und in Python:
import signal
import time
import multiprocessing
stop_event = multiprocessing.Event()
def stop(signum, frame):
stop_event.set()
signal.signal(signal.SIGTERM, stop)
if __== '__main__':
while not stop_event.is_set():
time.sleep(3)
Meine Frage ist nun, ob dieser Ansatz richtig ist. Muss ich mit zusätzlichen Signalen umgehen? Wird es ein "anständiger Unix-Daemon-Prozess" sein?
Angenommen, Ihr Daemon hat eine Art von kontinuierlicher Ausführung (irgendeine Ereignisschleife, verdreht, was auch immer), können Sie versuchen, upstart
zu verwenden.
Hier ist ein Beispiel für eine Upstart-Konfiguration für einen hypothetischen Python Service:
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
Wenn Sie dies als script.conf unter /etc/init
Speichern, führen Sie einfach einen einmaligen Vorgang durch
$ Sudo initctl reload-configuration
$ Sudo start script
Sie können es mit stop script
Stoppen. Die obige Konfig für den Neustart besagt, dass dieser Dienst beim Neustart gestartet und auch neu gestartet werden soll, wenn er abstirbt.
Was die Signalverarbeitung betrifft, sollte Ihr Prozess natürlich auf SIGTERM
reagieren. Standardmäßig sollte dies behandelt werden, es sei denn, Sie haben speziell Ihren eigenen Signalhandler installiert.
Rlotons Antwort ist gut. Hier ist eine leichte Verfeinerung, nur weil ich eine Menge Zeit mit dem Debuggen verbracht habe. Und ich muss eine neue Antwort machen, damit ich richtig formatieren kann.
Ein paar andere Punkte, die ich für immer zum Debuggen brauchte:
Hier ist meine 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