2008-09-22 28 views
10

¿Cuál sería la forma más sencilla de demonizar una secuencia de comandos python en Linux? Necesito que esto funcione con todos los sabores de Linux, por lo que solo debería usar herramientas basadas en Python.¿Cuál sería la forma más simple de demonizar una secuencia de comandos python en Linux?

+1

Una nota - por favor provea una forma de ejecutar su programa en el primer plano, tanto para la depuración y personas que prefieren herramientas de supervisión de procesos (tales como runit [http://smarden.org/runit] o daemontools [http://cr.yp.to/daemontools.html]) para ejecutar su programa como un servicio supervisado en lugar de un daemon. –

+0

Sí, estoy de acuerdo (estoy usando daemontools) – edomaur

+0

relacionado: [¿Cómo se crea un daemon en Python?] (Http://stackoverflow.com/q/473620/4279) – jfs

Respuesta

21

Ver Stevens y también esta lengthy thread on activestate que encontré personalmente para ser a la vez su mayor parte incorrecta y mucho que verbosa, y se me ocurrió esto:

from os import fork, setsid, umask, dup2 
from sys import stdin, stdout, stderr 

if fork(): exit(0) 
umask(0) 
setsid() 
if fork(): exit(0) 

stdout.flush() 
stderr.flush() 
si = file('/dev/null', 'r') 
so = file('/dev/null', 'a+') 
se = file('/dev/null', 'a+', 0) 
dup2(si.fileno(), stdin.fileno()) 
dup2(so.fileno(), stdout.fileno()) 
dup2(se.fileno(), stderr.fileno()) 

Si Es necesario detener el proceso nuevamente, se requiere conocer el pid, la solución habitual para esto es pidfiles. Para ello, si lo necesita

from os import getpid 
outfile = open(pid_file, 'w') 
outfile.write('%i' % getpid()) 
outfile.close() 

Por razones de seguridad que podría considerar cualquiera de estos después de demonizar

from os import setuid, setgid, chdir 
from pwd import getpwnam 
from grp import getgrnam 
setuid(getpwnam('someuser').pw_uid) 
setgid(getgrnam('somegroup').gr_gid) 
chdir('/') 

También es posible usar nohup pero que no funciona bien con python's subprocess module

+0

Interesante. ¿Cómo comienzas o paras el daemon? – edomaur

+0

Después de demonizar escribo un archivo pidfil –

+0

Bien, entonces después de eso puedo usar un script init.d estándar con sus ejemplos, debería ser el truco. – edomaur

1

Si no le importan los debates reales (que tienden a ser extraoficiales y no ofrecen una respuesta autorizada), puede elegir alguna biblioteca que le facilite la tarea. Recomendaría echar un vistazo a ll-xist, esta biblioteca contiene una gran cantidad de código salvavidas, como cron jobs helper, daemon framework, y (lo que no es interesante para usted, pero es realmente genial) orientado a objetos XSL (ll-xist sí mismo).

+0

Eso es un kit de biblioteca interesante, lo intentaré. Gracias. – edomaur

2

he utilizado recientemente Turkmenbashi:

$ easy_install turkmenbashi 
import Turkmenbashi 

class DebugDaemon (Turkmenbashi.Daemon): 

    def config(self): 
     self.debugging = True 

    def go(self): 
     self.debug('a debug message') 
     self.info('an info message') 
     self.warn('a warning message') 
     self.error('an error message') 
     self.critical('a critical message') 

if __name__=="__main__": 
    d = DebugDaemon() 
    d.config() 
    d.setenv(30, '/var/run/daemon.pid', '/tmp', None) 
    d.start(d.go) 
Cuestiones relacionadas