Обработка сообщений от дочернего процесса тщательно
-
24-10-2019 - |
Вопрос
Мой код 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 or
STDERR`, тогда вы можете сделать что -то вроде:
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()