2010-06-01 9 views
5

Tengo un programa en funcionamiento basado en Python que quiero ejecutar como daemon. Actualmente lo estoy haciendo de una manera muy hackish de iniciarlo en la sesión screen-d -m name y matarlo con pkill -9 -f name.¿Cómo administro un daemon basado en Python en Linux?

Finalmente estoy haciendo a tener que mover esto al mejor sistema que usamos aquí (por lo tanto No estoy dispuesto a modificar el programa) pero en el ínterin, estoy buscando una forma más limpia de hacer esta.

Mi pensamiento actual es iniciarlo como una tarea en segundo plano desde un script inti.d pero ¿cómo escribo la parte para volver a bajarlo?

Respuesta

1

Comenzando con un guión de estilo init.d es una buena manera. Descárguelo con POSIX Signals ... Consulte StackOverflow, Signal handling in Python.

+0

No puedo matar -9' por lo que a mí respecta, pero no sé cómo encontrar su PID de manera confiable. – BCS

+0

@BCS: '-9' es a menudo ... * exagerado * (perdón por el juego de palabras). Ver [kill -9] (http://speculation.org/garrick/kill-9.html). En cuanto a encontrar su PID, su secuencia de comandos puede crear un archivo pid en '/ var/run' o usar una lib que le permite establecer' argv [0] 'en un nombre fácilmente identificable para usar con' pkill'. –

6

En linux hay una utilidad start-stop-daemon como parte de las herramientas init.d.

Es muy flexible y permite diferentes formas de capturar el pid de su servidor.

También hay un archivo /etc/init.d/skeleton que puede servir como base para su propia secuencia de comandos init.d.

Si su plataforma de destino está basada en Debian, tiene sentido crear un paquete de Debina para implementarlo, ya que también ayuda a que un daemon se integre correctamente en el resto del sistema. Y no es demasiado complicado (si lo has hecho diez veces antes ;-)

+0

Parece algo bueno. – BCS

3

Si quieres hacerlo con el código en python, este es un método-C bastante normal que fue portado a Python que yo uso. Funciona sin problemas, e incluso puede elegir un archivo de salida.

import os 
import signal 
def daemonize(workingdir='.', umask=0,outfile='/dev/null'): 
#Put in background 
pid = os.fork() 
if pid == 0: 
    #First child 
    os.setsid() 
    pid = os.fork() #fork again 
    if pid == 0: 
     os.chdir(workingdir) 
     os.umask(umask) 
    else: 
     os._exit(0) 
else: 
    os._exit(0) 

#Close all open resources 
try: 
    os.close(0) 
    os.close(1) 
    os.close(2) 
except: 
    raise Exception("Unable to close standard output. Try running with 'nodaemon'") 
    os._exit(1) 

#Redirect output 
os.open(outfile, os.O_RDWR | os.O_CREAT) 
os.dup2(0,1) 
os.dup2(0,2) 

Luego, puede usar las señales para detectar cuando se envió una señal de interrupción al programa y salir muy bien. Ejemplo de Python Docs

import signal, os 

def handler(signum, frame): 
    print 'Signal handler called with signal', signum 
    raise IOError("Couldn't open device!") 

# Set the signal handler and a 5-second alarm 
signal.signal(signal.SIGALRM, handler) 
signal.alarm(5) 

# This open() may hang indefinitely 
fd = os.open('/dev/ttyS0', os.O_RDWR) 

signal.alarm(0)   # Disable the alarm 
+0

¡el método de doble horquilla funciona como un amuleto! – pygabriel

0

Pruebe esta solución question o más exactamente aceptado.

+0

Realmente preferiría no ensuciar con las partes internas del programa. Demonios, preferiría guardar lo que estoy usando ahora en lugar de hacer eso. – BCS

+0

Realmente no necesita cambiar su programa, si es importable. Justo importe su principal en deamon-ejemplo Método de ejecución, (reemplace while loop). – Ib33X

2

Hay módulos que podrían usarse para demonizar una secuencia de comandos python.

python-daemon implementa la especificación de daemon de buen comportamiento (PEP 3143).

También apareció this module en github que parece más pitónico y fácil de usar.

Cuestiones relacionadas