2010-06-26 7 views
5

J'ai ce code:python stdout cacher subprocess et attendre pour compléter

def method_a(self): 
    command_line = 'somtoolbox GrowingSOM ' + som_prop_path 
    subprocess.Popen(shlex.split(command_line)) 
    ...... 

def method_b(self): ..... 
.... 

et vous aime tous voir, method_a a un sous-processus qui appelle le programme somtoolbox. Mais ce programme a une longue sortie, et je veux le cacher. J'ai essayé:

subprocess.Popen(shlex.split(command_line), stdout=subprocess.PIPE) 

Mais il est revenu cette phrase:

cat: record error: Broked Pipe 

(ceci est une traduction de la phrase portugais: "chat: Erro de gravação: Tuyau quebrado") (je suis de Brésil)

En outre, j'ai d'autres méthodes (comme method_b), qui sont appelées après la méthode_a, et ces méthodes sont en cours d'exécution avant que le sous-processus ne termine le processus.

Comment est-ce que je peux cacher le stdout à tous (et ne le veux pas n'importe où), et faire l'autre code attendre que le sous-processus pour terminer l'exécution? Obs: Le somtoolbox est un programme java, qui donne la sortie longue au terminal. essayées:

outputTuple = subprocess.Popen(shlex.split(command_line), stdout = subprocess.PIPE).communicate() 

mais continu de sortie de retour à la coque. Aide!

Répondre

18

La meilleure façon de faire est de rediriger la sortie dans/dev/null. Vous pouvez le faire comme ceci:

devnull = open('/dev/null', 'w') 
subprocess.Popen(shlex.split(command_line), stdout=devnull) 

ensuite attendre jusqu'à ce qu'il soit fait, vous pouvez utiliser .wait() sur l'objet Popen, vous amener à ceci:

devnull = open('/dev/null', 'w') 
process = subprocess.Popen(shlex.split(command_line), stdout=devnull) 
retcode = process.wait() 

retcode contiendra alors la code de retour du processus.

ADDITIONAL: Comme mentionné dans les commentaires, cela ne cachera pas stderr. Pour cacher stderr aussi bien vous le feriez comme si:

devnull = open('/dev/null', 'w') 
process = subprocess.Popen(shlex.split(command_line), stdout=devnull, stderr=devnull) 
retcode = process.wait() 
+0

Il ne se cache pas –

+0

@Gabriel Peut-être que vous devez également rediriger stderr? –

+0

A travaillé! Merci beaucoup! –

5

Popen.communicate est utilisé pour attendre la fin du processus. Par exemple:

from subprocess import PIPE, Popen 
outputTuple = Popen(["gcc", "--version"], stdout = PIPE).communicate() 

retournera un tuple de chaînes, une pour stdout et un autre pour la sortie stderr.

+0

Cela ne fonctionnait pas. Vois ma dernière phrase, pour voir si ça change quelque chose. C'est une sortie d'un programme Java ... voir là, s'il vous plaît. –

+2

Ajoutez simplement ', stderr = PIPE'. – AndiDog

Questions connexes