¿Cómo se crea un daemon en Python?


Answers

Hay muchas cosas difíciles de cuidar cuando se convierte en un proceso de demonio de buen comportamiento :

  • previene los volcados del núcleo (muchos daemons se ejecutan como root y los volcados del núcleo pueden contener información sensible)

  • comportarse correctamente dentro de una prisión de chroot

  • establece UID, GID, directorio de trabajo, umask y otros parámetros de proceso de forma adecuada para el caso de uso

  • renunciar a suid elevado, privilegios sgid

  • cierre todos los descriptores de archivos abiertos, con exclusiones según el caso de uso

  • comportarse correctamente si se inicia dentro de un contexto ya aislado, como init , inetd , etc.

  • configure manejadores de señal para el comportamiento de daemon sensible, pero también con manejadores específicos determinados por el caso de uso

  • redirigir las corrientes estándar stdin , stdout , stderr ya que un proceso daemon ya no tiene una terminal controladora

  • manejar un archivo PID como un bloqueo de asesoramiento cooperativo, que es una lata de gusanos en sí misma con muchas formas contradictorias pero válidas de comportarse

  • permitir una limpieza adecuada cuando el proceso finaliza

  • en realidad se convierta en un proceso demoníaco sin conducir a zombies

Algunos de estos son estándar , como se describe en la literatura canónica de Unix ( Programación avanzada en el entorno UNIX , por el difunto W. Richard Stevens, Addison-Wesley, 1992). Otros, como la redirección de flujo y el manejo de archivos PID , son un comportamiento convencional que la mayoría de los usuarios de daemon esperarían pero que están menos estandarizados.

Todos estos están cubiertos por la especificación PEP 3143 "Biblioteca de procesos daemon estándar" . La implementación de referencia pypi.python.org/pypi/python-daemon funciona en Python 2.7 o posterior, y Python 3.2 o posterior.

Question

La búsqueda en Google revela fragmentos de código x2. El primer resultado es esta receta de código que tiene mucha documentación y explicación, junto con algunas discusiones útiles debajo.

Sin embargo, otra muestra de código , aunque no contiene tanta documentación, incluye código de muestra para pasar comandos como inicio, detención y reinicio. También crea un archivo PID que puede ser útil para verificar si el daemon ya se está ejecutando, etc.

Estas muestras explican cómo crear el daemon. ¿Hay alguna cosa adicional que deba ser considerada? ¿Una muestra es mejor que la otra y por qué?




dado que python-daemon aún no ha sido compatible con Python 3.x, y de lo que se puede leer en la lista de correo, puede que nunca lo haga, he escrito una nueva implementación de PEP 3143: pep3143daemon

pep3143daemon debería soportar al menos Python 2.6, 2.7 y 3.x

También contiene una clase PidFile.

La biblioteca solo depende de la biblioteca estándar y del módulo seis.

Se puede usar como reemplazo en reemplazo de python-daemon.

Aquí está la documentation .




Modifiqué algunas líneas en el ejemplo del código de Sander Marechal (mencionado por @JeffBauer en la respuesta aceptada ) para agregar un método quit() que se ejecuta antes de que se detenga el daemon. Esto a veces es muy útil.

Aquí está.

Nota: No uso el módulo "python-daemon" porque todavía falta la documentación (vea también muchas otras preguntas de SO) y es bastante oscuro (¿cómo iniciar / detener correctamente un daemon desde la línea de comandos con este módulo?)




Tenga en cuenta el paquete pypi.python.org/pypi/python-daemon que resuelve muchos problemas detrás de demonios listos para usar.

Entre otras características, permite (a partir de la descripción del paquete Debian):

  • Separe el proceso en su propio grupo de procesos.
  • Establezca el entorno de proceso apropiado para ejecutar dentro de un chroot.
  • Renounce los privilegios suid y sgid.
  • Cierre todos los descriptores de archivos abiertos.
  • Cambie el directorio de trabajo, uid, gid y umask.
  • Establecer manejadores de señal apropiados.
  • Abra nuevas descripciones de archivos para stdin, stdout y stderr.
  • Administre un archivo de bloqueo de PID especificado.
  • Registre las funciones de limpieza para el proceso de salida.



La forma más fácil de crear daemon con Python es usar el marco Twisted orientado a eventos. Maneja todas las cosas necesarias para la daemonización para usted. Utiliza el patrón Reactor para manejar solicitudes simultáneas.




Esta función transformará una aplicación en un daemon:

import sys
import os

def daemonize():
    try:
        pid = os.fork()
        if pid > 0:
            # exit first parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #1 failed: {0}\n'.format(err))
        sys.exit(1)
    # decouple from parent environment
    os.chdir('/')
    os.setsid()
    os.umask(0)
    # do second fork
    try:
        pid = os.fork()
        if pid > 0:
            # exit from second parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #2 failed: {0}\n'.format(err))
        sys.exit(1)
    # redirect standard file descriptors
    sys.stdout.flush()
    sys.stderr.flush()
    si = open(os.devnull, 'r')
    so = open(os.devnull, 'w')
    se = open(os.devnull, 'w')
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())



Probablemente no sea una respuesta directa a la pregunta, pero systemd puede usarse para ejecutar su aplicación como daemon. Aquí hay un ejemplo:

[Unit]
Description=Python daemon
After=syslog.target
After=network.target

[Service]
Type=simple
User=<run as user>
Group=<run as group group>
ExecStart=/usr/bin/python <python script home>/script.py

# Give the script some time to startup
TimeoutSec=300

[Install]
WantedBy=multi-user.target

Prefiero este método porque una gran parte del trabajo está hecho para ti, y luego tu script daemon se comporta de manera similar al resto de tu sistema.

-O por




Links