web-dev-qa-db-fra.com

Python Subprocess.Popen à partir d'un thread

J'essaie de lancer un "rsync" en utilisant le module de sous-processus et Popen à l'intérieur d'un thread. Après avoir appelé le rsync, je dois également lire la sortie. J'utilise la méthode de communication pour lire la sortie. Le code fonctionne bien 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 lorsque je mets Shell = False, je ne reçois rien de la communication lors de l'exécution dans un thread.

27
noahd

Vous n'avez fourni aucun code à examiner, mais voici un exemple qui fait quelque chose de similaire à 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
39
Ryan Bright

Voici une excellente implémentation n'utilisant pas de threads: constamment-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'])
13
nmanos