2009-06-12 7 views
21

J'essaie de lancer un 'rsync' en utilisant un module de sous-processus et Popen à l'intérieur d'un thread. Après avoir appelé le rsync, j'ai besoin de lire la sortie. J'utilise la méthode de communication pour lire la sortie. Le code fonctionne correctement lorsque je n'utilise pas de thread. Il semble que lorsque j'utilise un thread, il se bloque sur l'appel de communication. Une autre chose que j'ai remarquée est que quand je mets shell = False je ne reçois rien de la communication quand je cours dans un thread.Python Subprocess.Popen à partir d'un thread

Répondre

33

Vous n'avez pas fourni de code pour nous à regarder, mais voici un exemple qui fait quelque chose de semblable à ce que vous décrivez:

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

Oui c'est à peu près exactement ce que je fais. J'aimerais bien lire la sortie dans le fil. Je devrais également noter que j'utilise Python 2.3. J'ai saisi une copie du sous-processus de 2.4. – noahd

+0

alors s'il vous plaît marquer cela comme "répondu" –

+0

Je devrais être plus clair que c'est ce que je fais, mais cela ne fonctionne pas. Dans ce cas, l'appel de communication ne retournera rien et la commande ne semble pas s'exécuter. Si je mets shell = True la communication bloque le thread. Ensuite, après avoir arrêté le python, je me retrouve avec un processus ssh défunt. – noahd

9

Voici une grande mise en œuvre n'utilisant des fils: 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

Il convient de noter que cette implémentation bloquera sur 'process.stdout.readline()'. – Ian

Questions connexes