J'ai essayé de faire des choses comme ça:
subprocess.Popen(['Nohup', 'my_command'],
stdout=open('/dev/null', 'w'),
stderr=open('logfile.log', 'a'))
Cela fonctionne si le script parent se termine correctement, mais si je tue le script (Ctrl-C), tous mes processus enfants sont également tués. Y a-t-il un moyen d'éviter cela?
Les plates-formes dont je me soucie sont OS X et Linux, en utilisant Python 2.6 et Python 2.7.
La façon habituelle de le faire sur les systèmes Unix est de bifurquer et de quitter si vous êtes le parent. Jetez un œil à os.fork()
.
Voici une fonction qui fait le travail:
def spawnDaemon(func):
# do the UNIX double-fork magic, see Stevens' "Advanced
# Programming in the UNIX Environment" for details (ISBN 0201563177)
try:
pid = os.fork()
if pid > 0:
# parent process, return and keep running
return
except OSError, e:
print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
os.setsid()
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
# do stuff
func()
# all done
os._exit(os.EX_OK)
Le processus enfant reçoit le même SIGINT que votre processus parent car il se trouve dans le même groupe de processus. Vous pouvez placer l'enfant dans son propre groupe de processus en appelant os.setpgrp () dans le processus enfant. L'argument preexec_fn de Popen est utile ici:
subprocess.Popen(['Nohup', 'my_command'],
stdout=open('/dev/null', 'w'),
stderr=open('logfile.log', 'a'),
preexec_fn=os.setpgrp
)
(preexec_fn est uniquement pour un * x-oids. Il semble y avoir un équivalent approximatif pour Windows "creationflags = CREATE_NEW_PROCESS_GROUP", mais je ne l'ai jamais essayé.)