2010-06-26 1 views
5

у меня есть этот код:питон подпроцесс скрыть стандартный вывод и ждать его, чтобы закончить

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

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

и как вы все видите, method_a имеет подпроцесс, который звонит программу somtoolbox. Но у этой программы есть длинный stdout, и я хочу скрыть это. Я пробовал:

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

Но он вернулся это предложение:

cat: record error: Broked Pipe 

(это перевод португальского предложения: "кошка: Эрро де gravação: Труба quebrado") (я из brazil)

Кроме того, у меня есть другие методы (например method_b), которые вызывается после метода method_a, а tis-методы выполняются до того, как подпроцесс завершит процесс.

Как я могу скрыть stdout вообще (и не хочу его нигде), и заставить другой код ждать, пока подпроцесс завершит выполнение?

Obs: Somtoolbox представляет собой программу java, которая дает длинный вывод на терминал. Пробовал:

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

но непрерывное возвращение выхода к корпусу. Помощь!

ответ

18

Лучший способ сделать это - перенаправить вывод в/dev/null. Вы можете сделать это так:

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

Затем ждать, пока это не будет сделано, вы можете использовать .wait() на объекте POPEN, получая вас к этому:

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

RETCODE будет содержать код возврата процесса.

ДОПОЛНИТЕЛЬНО: Как уже упоминалось в комментариях, это не скроет stderr. Чтобы скрыть stderr, вы сделаете это так:

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

Это не скрытие –

+0

@Gabriel Возможно, вам нужно перенаправить stderr тоже? –

+0

Работал! Спасибо огромное! –

5

Popen.communicate Используется для ожидания завершения процесса. Например:

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

возвращает кортеж из строк, один для стандартного вывода и другой для вывода Stderr.

+0

Это не сработало. Посмотрите мою последнюю фразу, чтобы узнать, не изменилось ли это. Его выход из программы java ... см. Там, пожалуйста. –

+2

Просто добавьте ', stderr = PIPE'. – AndiDog