2011-05-15 19 views
27

böyle şeyler çalışan denedim öldürülürse sonra çalışmaya devam sahiptir:piton bir program çalıştırın ve komut

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

ben öldürsem Bu ana komut incelikle çıkar eğer çalışır, ancak komut dosyası (Ctrl-C), tüm çocuk süreçlerim de öldürülür. Bundan kaçınmanın bir yolu var mı?

Üzerinde durduğum platformlar OS X ve Linux, Python 2.6 ve Python 2.7.

cevap

22

Unix sistemlerinde bunu yapmak için alışılagelmiş bir yol, ebeveyn iseniz, çatal çırpmaktır. os.fork()'a bir göz atın. Daha fazla bilgi için here'a bakabilirsiniz.

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

Eğer çatallanır ve sonra çatalın yarısını öldürürüm (çıkmasına izin vermek yerine), bu yeni süreci öldürecek mi? – James

+1

Tamam, daha fazla okumadan sonra: bu sinyalleri almaktan kaçınmak için iki kez forking gerektirir? Ebeveyn sürecinin etkileşime devam etmesini çok isterdim --- onun işi, ortaya çıktığı süreçleri izlemesidir - eğer kabuğunu reddetmek zorundaysa, bu mümkün değildir. – James

+0

Teşekkürler! Uygulamamı cevabınıza ekledim. – James

-6

çalıştırın subprocess.Popen() ayrı bir konu:

Burada iş yapan bir fonksiyondur.

+0

Bu işe yaramıyor. – James

39

Alt işlem, aynı işlem grubunda olduğu için ana işleminizle aynı SIGINT alır. Çocuğun kendi süreç grubunda çocuk süreçlerine os.setpgrp() diyerek koyabilirsiniz. POPEN en preexec_fn argümanı burada yararlıdır:

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

(preexec_fn sadece un * x-OIDler içindir var "creationflags = CREATE_NEW_PROCESS_GROUP" Windows için kaba bir eşdeğer gibi görünüyor, ama ben hiç denemedim..)

+0

Cevabınız için teşekkürler; benim için çalışıyor! Ancak, bir zaman sonra komutumun durması (süreç ölür), eğer stdout ve stderr agruments'ını çıkarırsam merak ediyorum. – danuker