2009-06-12 15 views
21

Ich versuche, ein 'rsync' mit Subprozess-Modul und Popen innerhalb eines Threads zu starten. Nachdem ich das rsync aufgerufen habe, muss ich auch die Ausgabe lesen. Ich verwende die Kommunikationsmethode, um die Ausgabe zu lesen. Der Code läuft gut, wenn ich keinen Thread verwende. Es scheint, dass wenn ich einen Thread verwende, er an dem Kommunikationsaufruf hängt. Eine andere Sache, die ich bemerkt habe, ist, dass wenn ich shell = False setze, bekomme ich nichts zurück von der Kommunikation, wenn ich in einem Thread laufe.Python Subprocess.Popen von einem Thread

Antwort

33

Sie liefern keinen Code für uns zu sehen, aber hier ist ein Beispiel, das etwas ähnliches tut, was Sie beschreiben:

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

Ja das ist ziemlich genau was ich mache. Ich möchte jedoch die Ausgabe innerhalb des Threads gelesen werden. Ich sollte auch beachten, dass ich Python 2.3 verwende. Ich habe eine Kopie des Subprozesses von 2.4. – noahd

+0

dann bitte markieren Sie diese als "beantwortet" –

+0

Ich sollte klarer sein, dass das ist, was ich tue, aber es funktioniert nicht. In diesem Fall gibt der Kommunikationsaufruf nichts zurück und der Befehl scheint nicht ausgeführt zu werden. Wenn ich shell = True setze, hängt die Kommunikation den Thread. Dann, nachdem ich den Python gestoppt habe, habe ich einen nicht mehr existierenden ssh-Prozess. – noahd

9

Hier ist eine große Implementierung nicht Threads: 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

Es sollte beachtet werden, dass diese Implementierung auf 'process.stdout.readline()' blockiert. – Ian

Verwandte Themen