2011-05-15 9 views
27

が、私はこのようなものを実行してみた殺された後、それを実行し続ける必要があり:のpythonからプログラムを実行し、スクリプトが

subprocess.Popen(['nohup', 'my_command'], 
       stdout=open('/dev/null', 'w'), 
       stderr=open('logfile.log', 'a')) 

私が殺す場合、これは親スクリプトが正常に終了した場合に動作しますが、スクリプト(Ctrl + C)を押すと、すべての子プロセスも強制終了されます。これを避ける方法はありますか?

私が気になるプラットフォームは、Python 2.6 Python 2.7を使用しているOS XとLinuxです。

答えて

22

Unixシステムでこれを行う通常の方法は、あなたが親の場合はforkして終了することです。 os.fork()をご覧ください。詳細はhereをご覧ください。

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) 
+0

私はフォークし、フォークの半分を(それを終了させるのではなく)殺すと、新しいプロセスが終了しますか? – James

+1

これを読んだら、信号を受信しないようにするためにはフォークが2回必要ですか?私は親プロセスがインタラクティブなままであることをとても望んでいます---その仕事はそれが生成するプロセスを監視することです---それはシェルを否定しなければならない場合不可能です。 – James

+0

ありがとう!あなたの答えに実装を追加しました。 – James

-6

実行subprocess.Popen()別のスレッドで:

はここで仕事をしていません機能です。

+0

これはうまくいかないようです。 – James

39

子プロセスは、同じプロセスグループに属しているため、親プロセスと同じ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" ように見えますが、私はそれを試したことがありません。。)

+0

あなたの答えをありがとう。わたしにはできる!しかし、私が 'stdout'と' stderr'手段を省略すると、私のコマンドがなぜ止まる(プロセスが死ぬ)のか不思議です。 – danuker

関連する問題