2009-06-12 9 views
21

Próbuję uruchomić "rsync" przy użyciu modułu podprocesowego i Popen wewnątrz wątku. Po wywołaniu rsync muszę również przeczytać dane wyjściowe. Używam metody komunikacji, aby odczytać wynik. Kod działa poprawnie, gdy nie używam wątku. Wygląda na to, że kiedy używam wątku, zawiesza się on na połączeniu komunikacyjnym. Inną rzeczą, którą zauważyłem jest to, że kiedy ustawiam shell = False, nic nie odzyskają komunikacji podczas działania w wątku.Podproces Pythona.Popen z wątku

Odpowiedz

33

Nie dostarczamy żadnego kodu dla nas patrzeć, ale tutaj jest próbka, która robi coś podobnego do tego, co można opisać:

import threading 
import subprocess 

class MyClass(threading.Thread): 
    def __init__(self): 
     self.stdout = None 
     self.stderr = None 
     threading.Thread.__init__(self) 

    def run(self): 
     p = subprocess.Popen('rsync -av /etc/passwd /tmp'.split(), 
          shell=False, 
          stdout=subprocess.PIPE, 
          stderr=subprocess.PIPE) 

     self.stdout, self.stderr = p.communicate() 

myclass = MyClass() 
myclass.start() 
myclass.join() 
print myclass.stdout 
+0

Tak, to dokładnie to, co robię. Chciałbym jednak przeczytać wynik w wątku. Powinienem również zauważyć, że używam Pythona 2.3. Zdobyłem kopię podprocesu z 2.4. – noahd

+0

następnie proszę oznaczyć to jako "odpowiedział" –

+0

Powinienem być bardziej jasne, że to, co robię, ale to nie działa. W takim przypadku wywołanie komunikacyjne nie zwróci niczego, a polecenie nie wydaje się być wykonywane. Jeśli ustawię shell = True, komenda zawiesza wątek. Następnie po zatrzymaniu pytona kończę z nieistniejącym procesem ssh. – noahd

9

Oto wielka realizacja nie używając wątki: constantly-print-subprocess-output-while-process-is-running

import subprocess 

def execute(command): 
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
    output = '' 

    # Poll process for new output until finished 
    for line in iter(process.stdout.readline, ""): 
     print line, 
     output += line 


    process.wait() 
    exitCode = process.returncode 

    if (exitCode == 0): 
     return output 
    else: 
     raise Exception(command, exitCode, output) 

execute(['ping', 'localhost']) 
+4

Należy zauważyć, że ta implementacja będzie blokować na 'process.stdout.readline()'. – Ian

Powiązane problemy