Обработка сообщений от дочернего процесса тщательно

StackOverflow https://stackoverflow.com/questions/4805576

Вопрос

Мой код Python порождает дочерний процесс, и он печатает сообщения как Stdout, так и Stderr. Мне нужно распечатать их по -другому.

У меня есть следующий код, чтобы породить дочерний процесс и получить результат Stdout от него.

cmd = ["vsmake.exe", "-f"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
for line in iter(p.stdout.readline, ''):
    print line,
    sys.stdout.flush()
    pass
p.wait()

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

ДОБАВЛЕН

Мне нужно распечатать STDERR и STDOUT, как только дочерний процесс что -то распечатывает. И это кросс -платформная реализация, поэтому она должна работать на Mac/Linux/ПК.

Это было полезно?

Решение

p = Popen(cmd, bufsize=1024,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
p.stdin.close()
print p.stdout.read() #This will print the standard output from the spawned process
print p.stderr.read() #This is what you need, error output <-----

Таким образом, в основном выходной сигнал перенаправляется на stderr Трубка.

Если вам нужно что -то большее в реальном времени. Я имею в виду линии, напечатанные, как только породившийся процесс что -то напечатает stdout orSTDERR`, тогда вы можете сделать что -то вроде:

def print_pipe(type_pipe,pipe):
    for line in iter(pipe.readline, ''):
         print "[%s] %s"%(type_pipe,line),

p = Popen(cmd, bufsize=1024,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)

t1 = Thread(target=print_pipe, args=("stdout",p.stdout,))
t1.start()
t2 = Thread(target=print_pipe, args=("stderr",p.stderr,))
t2.start()

#optionally you can join the threads to wait till p is done. This is avoidable but it 
# really depends on the application.
t1.join()
t2.join()

В этом случае два потока будут печатать каждый раз, когда строка записывается либо на stdout или же stderr. Анкет Параметр type_pipe просто делает различие, когда линии печатаются, чтобы узнать, что они приходят stderr или же stdout.

Другие советы

Самый простой способ сделать эту платформу независимо от использования потоков (к сожалению). Вот какой -то пример кода:

def redirect_to_stdout(stream):
    for line in stream:
        sys.stdout.write(line)
        sys.stdout.flush()

cmd = ["vsmake.exe", "-f"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stderr_thread = threading.Thread(target=redirect_to_stdout, args=(p.stderr,))
stderr_thread.start()
redirect_to_stdout(p.stdout)
p.wait()
stderr_thread.join()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top