run - python script as a linux service
Script de Python como servicio/daemon de Linux (2)
Asumiendo que tu daemon tiene alguna manera de funcionar continuamente (algún bucle de evento, retorcido, lo que sea), puedes intentar usar upstart
.
Aquí hay una configuración advenediza de ejemplo para un servicio hipotético de 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 guarda esto como script.conf en /etc/init
, simplemente haga una sola vez
$ sudo initctl reload-configuration
$ sudo start script
Puedes detenerlo con stop script
. Lo que dice la nueva versión del upstart conf es iniciar este servicio al reiniciar y también reiniciarlo si se muere.
En cuanto a la gestión de señal, su proceso debería responder naturalmente a SIGTERM
. De forma predeterminada, esto debe manejarse a menos que haya instalado específicamente su propio manejador de señal.
Hola,
Intento dejar que una secuencia de comandos python se ejecute como servicio (daemon) en (ubuntu) linux.
En la web existen varias soluciones como:
http://pypi.python.org/pypi/python-daemon/
Un proceso de demonio Unix que se comporta bien es difícil de acertar, pero los pasos necesarios son muy similares para cada programa de daemon. Una instancia de DaemonContext contiene el comportamiento y el entorno de proceso configurado para el programa; use la instancia como administrador de contexto para ingresar un estado de daemon.
http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
Sin embargo, como quiero integrar mi script python específicamente con ubuntu linux, mi solución es una combinación con 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
y 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 __name__ == ''__main__'':
while not stop_event.is_set():
time.sleep(3)
Mi pregunta ahora es si este enfoque es correcto. ¿Debo manejar alguna señal adicional? ¿Será un "proceso de demonio de Unix de buen comportamiento"?
La respuesta de Rloton es buena. Aquí hay un refinamiento ligero, solo porque pasé un montón de tiempo depurando. Y necesito hacer una nueva respuesta para poder formatear correctamente.
Un par de otros puntos que me llevaron a depurar para siempre:
- Cuando falla, primero revisa /var/log/upstart/.log
- Si su secuencia de comandos implementa un daemon con python-daemon , NO usa la estrofa ''expect daemon''. No tener ''esperar'' funciona. No sé por qué. (Si alguien sabe por qué, por favor publique!)
- Además, siga revisando "script de estado de initctl" para asegurarse de que está activo (inicio / ejecución). (y vuelve a cargar cuando actualices tu archivo conf)
Aquí está mi versión:
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