2009-06-12 17 views
21

Sto provando a lanciare un 'rsync' usando il sottoprocesso modulo e Popen all'interno di una discussione. Dopo aver chiamato rsync, ho bisogno di leggere anche l'output. Sto usando il metodo di comunicazione per leggere l'output. Il codice funziona correttamente quando non utilizzo un thread. Sembra che quando uso un thread si blocca sulla chiamata di comunicazione. Un'altra cosa che ho notato è che quando ho impostato shell = False non ricevo nulla dalla comunicazione durante l'esecuzione in una discussione.Subprocesso Python.Popen da una discussione

risposta

33

Lei non ha fornito alcun codice per noi a guardare, ma qui è un campione che fa qualcosa di simile a ciò che si descrive:

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

Sì, è esattamente ciò che sto facendo. Mi piacerebbe essere letto l'output all'interno del thread però. Dovrei anche notare che sto usando Python 2.3. Ho preso una copia del sottoprocesso dalla 2.4. – noahd

+0

quindi si prega di contrassegnare come "risposta" –

+0

Dovrei essere più chiaro che è quello che sto facendo, ma non funziona. In questo caso la chiamata di comunicazione non restituirà nulla e il comando non sembra essere eseguito. Se imposto shell = True la comunicazione blocca il thread. Poi, dopo aver fermato il pitone, ho finito con un processo ssh defunto. – noahd

9

Ecco una grande implementazione non utilizza le discussioni: 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

Va notato che questa implementazione verrà bloccata su 'process.stdout.readline()'. – Ian

Problemi correlati