Как распечатать выходные данные из вызовов подпроцесса. Открыть (...) в цикле? - PullRequest
4 голосов
/ 03 апреля 2009

Я написал скрипт для запуска программы командной строки с различными входными аргументами и получения определенной строки из выходных данных. У меня в цикле работает следующее:

p1 = subprocess.Popen(["program", args], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=False)
p2 = subprocess.Popen(["grep", phrase], stdin=p1.stdout, stdout=subprocess.PIPE, shell=False)
p1.wait()
p2.wait()
p = str(p2.stdout.readlines())
print 'p is ', p

Одна из проблем заключается в том, что вывод завершается только после завершения цикла. Я хочу напечатать что-нибудь каждый раз, когда процесс закончен. Как я могу это сделать?

Кроме того, я хочу иметь возможность отображать вывод p1. Но я не могу взять его с помощью p1.stdout.readlines (), не нарушив p2. Как я могу это сделать?

Я думал, что просто не могу сделать вызов grep, сохранить выходные данные p1 и найти фразу, но есть много выходных данных, поэтому этот способ кажется довольно неэффективным.

Любые предложения будут с благодарностью. Спасибо!

Ответы [ 2 ]

2 голосов
/ 05 апреля 2009

Вот быстрый взлом, который работал для меня в Linux. Это может работать для вас, в зависимости от ваших требований. Он использует tee в качестве фильтра, который, если вы передадите print_all вашему сценарию, скопирует дополнительную копию в / dev / tty (эй, я сказал, что это был хак) :

#!/usr/bin/env python

import subprocess
import sys

phrase = "bar"
if len(sys.argv) > 1 and sys.argv[1] == 'print_all':
    tee_args = ['tee', '/dev/tty']
else:
    tee_args = ['tee']

p1 = subprocess.Popen(["./program"], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=False)
p2 = subprocess.Popen(tee_args, stdin=p1.stdout, stdout=subprocess.PIPE, shell=False)
p3 = subprocess.Popen(["grep", phrase], stdin=p2.stdout, stdout=subprocess.PIPE, shell=False)
p1.wait()
p2.wait()
p3.wait()
p = str(p3.stdout.readlines())
print 'p is ', p

Со следующим содержанием program:

#!/bin/sh

echo foo
echo bar
echo baz

Пример вывода:

$ ./foo13.py
p is  ['bar\n']
$ ./foo13.py print_all
foo
bar
baz
p is  ['bar\n']
1 голос
/ 03 апреля 2009

Попробуйте вызывать sys.stdout.flush () после каждого оператора печати. ​​

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...