Bonjour,
J'essaie de laisser un script python s'exécuter en tant que service (démon) sur (ubuntu) linux.
Sur le web il existe plusieurs solutions comme:
http://pypi.python.org/pypi/python-daemon/
Un processus démon Unix bien comporté est difficile à réaliser, mais les étapes requises sont sensiblement les mêmes pour chaque programme démon. Une instance DaemonContext contient le comportement et l'environnement de processus configuré pour le programme; utilisez l'instance comme gestionnaire de contexte pour entrer dans un état de démon.
http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
Cependant, comme je veux intégrer mon script python spécifiquement avec ubuntu linux, ma solution est une combinaison avec un script 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 "$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
et en 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)
Ma question est maintenant de savoir si cette approche est correcte. Dois-je gérer des signaux supplémentaires? Sera-ce un "processus démon Unix bien comporté"?
En supposant que votre démon a un moyen de s'exécuter continuellement (une boucle d'événement, une torsion, peu importe), vous pouvez essayer d'utiliser upstart
.
Voici un exemple de configuration parvenu pour un service hypothétique Python:
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
Si vous l'enregistrez en tant que script.conf dans /etc/init
vous faites simplement une fois
$ Sudo initctl reload-configuration
$ Sudo start script
Vous pouvez l'arrêter avec stop script
. Qu'est-ce que la conf upstart ci-dessus dit est de démarrer ce service lors des redémarrages et également le redémarrer s'il meurt.
Quant à la gestion du signal - votre processus devrait naturellement répondre à SIGTERM
. Par défaut, cela doit être géré sauf si vous avez spécifiquement installé votre propre gestionnaire de signaux.
La réponse de Rloton est bonne. Voici un léger raffinement, juste parce que j'ai passé une tonne de débogage. Et je dois faire une nouvelle réponse pour pouvoir formater correctement.
Quelques autres points qui m'ont pris une éternité pour déboguer:
Voici ma 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