如何在循环中打印调用subprocess.Popen(...)的输出?

时间:2009-04-03 17:20:34

标签: python subprocess

我编写了一个脚本来运行带有不同输入参数的命令行程序,并从输出中获取某一行。我在循环中运行以下内容:

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的输出选项。但我无法在不破坏p2的情况下使用p1.stdout.readlines()获取它。我怎么能这样做?

我原以为我不能调用grep,存储p1的输出并搜索短语,但是输出很多,所以这种方式看起来效率很低。

任何建议都将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:2)

这是一个在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 :(得分:1)

尝试在每个print语句后调用sys.stdout.flush()。