Quale sarebbe il modo più semplice per demonizzare uno script Python in Linux?
Domanda
Quale sarebbe il modo più semplice per demonizzare uno script Python in Linux? Ho bisogno che funzioni con ogni tipo di Linux, quindi dovrebbe usare solo strumenti basati su Python.
Soluzione
Vedi Stevens e anche questo thread lungo su activestate che ho trovato personalmente sia per lo più errato che molto dettagliato, e ho trovato questo:
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())
Se è necessario interrompere nuovamente tale processo, è necessario conoscere il pid, la soluzione abituale a questo è pidfile. Fallo se ne hai bisogno
from os import getpid
outfile = open(pid_file, 'w')
outfile.write('%i' % getpid())
outfile.close()
Per motivi di sicurezza potresti considerare uno di questi dopo aver demonizzato
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('/')
Puoi anche usare nohup ma questo non funziona bene con modulo di sottoprocesso di python
Altri suggerimenti
Di recente ho usato 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)
Se non ti interessano le discussioni effettive (che tendono ad andare fuori tema e non offrono una risposta autorevole), puoi scegliere alcune librerie che renderanno più semplici i tuoi gusti. Consiglierei di dare un'occhiata a ll-xist , questa libreria contiene molti codice salvavita, come cron jobs helper, daemon framework e (cosa che non ti interessa, ma è davvero eccezionale) XSL orientata agli oggetti (ll-xist stesso)
Usa grizzled.os.daemonize :
$ easy_install grizzled
>>> from grizzled.os import daemonize
>>> daemon.daemonize()
Per capire come funziona o per farlo da solo, leggi la discussione su ActiveState .