私はこのようなものを実行しようとしました:
subprocess.Popen(['Nohup', 'my_command'],
stdout=open('/dev/null', 'w'),
stderr=open('logfile.log', 'a'))
これは、親スクリプトが正常に終了した場合に機能しますが、スクリプトを強制終了(Ctrl-C)すると、すべての子プロセスも強制終了されます。これを回避する方法はありますか?
私が気にするプラットフォームはOS XとLinuxで、Python 2.6 and Python 2.7。
Unixシステムでこれを行う通常の方法は、親である場合は分岐して終了することです。 os.fork()
をご覧ください。
仕事をする関数は次のとおりです。
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)
子プロセスは、同じプロセスグループにあるため、親プロセスと同じSIGINTを受け取ります。子プロセスでos.setpgrp()を呼び出すことにより、子を独自のプロセスグループに配置できます。 Popenのpreexec_fn引数はここで役立ちます:
subprocess.Popen(['Nohup', 'my_command'],
stdout=open('/dev/null', 'w'),
stderr=open('logfile.log', 'a'),
preexec_fn=os.setpgrp
)
(preexec_fnはun * x-oid専用です。Windowsの「creationflags = CREATE_NEW_PROCESS_GROUP」と大まかに同等のものがあるようですが、試したことはありません。)