Python Popen stdout输出进入stderr

时间:2014-03-28 05:52:16

标签: python subprocess wireshark tshark

我必须使用python tshark -D捕获subprocess的输出。 这是tshark -D输出,

$ tshark -D 1. eth0 2. any (Pseudo-device that captures on all interfaces) 3. lo 并使用python,

>>> import subprocess
>>> p = subprocess.Popen(["tshark", "-D"], stdout=subprocess.PIPE) ###1
>>> 1. eth0
2. any (Pseudo-device that captures on all interfaces)
3. lo
>>> p = subprocess.Popen(["tshark", "-D"], stderr=subprocess.PIPE,stdout=subprocess.PIPE) ###2
>>> p.stderr.read()
'1. eth0\n2. any (Pseudo-device that captures on all interfaces)\n3. lo\n'
>>> p.stdout.read()
''

在#1中,输入命令后输出。在#2中,所需的输出来自stderr。为什么会给出这样的结果?

3 个答案:

答案 0 :(得分:2)

要获得所有输出,无论子进程是在stdout还是stderr上打印,您都可以使用stderr=STDOUTsubprocess.check_output

from subprocess import check_output, STDOUT

all_output = check_output(['tshark', '-D'], stderr=STDOUT)

tshark手册说:

  

-D打印TShark可以捕获的接口列表,然后退出。

它没有指定输出必须在stderr上。虽然在我的系统上它只向stderr打印诊断信息。 Stdout可能会被保留用于打印捕获的数据。

答案 1 :(得分:0)

tshark -D始终打印到stderr。在#1的情况下,由于您没有捕获stderr,它将被打印到您的控制台。

在#2的情况下,由于你同时捕获了stdout和stderr,stdout ==> ''和stderr ==>输出。

答案 2 :(得分:0)

对于#1: 因为您没有处理标准管道和输出,所以打印出来的命令将只在屏幕上打印出来。如果要处理标准管道,则需要同时处理stdout和stderr。否则你实际上无法捕获标准管道。指定标准管道时,应同时处理标准错误打印输出。

如果你在名为“func_my.py”的模块下有一个函数,那么下面会更像这样:

def func_my():
    print "Hello"
    return "World"

if __name__ == "__main__":
    func_my()

当你调用这个函数时,如果你不处理控制台输出,字符串“hello”将直接显示在控制台输出中。

p = subprocess.Popen(["python", "func_my.py"], stdout=subprocess.PIPE)

这将始终打印“你好”。

对于#2:你确实捕获了标准输出和错误输出,但是你犯了一个错误。你把所有的管道都放到了stdout和stderr上。正确的方式应该是:

p = subprocess.Popen(["tshark", "-D"], stderr=subprocess.STDOUT,stdout=subprocess.PIPE)
p.stderr.read()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'read'
p.stdout.read()
"WARNING: gnome-keyring:: couldn't connect to: /tmp/keyring-UBTaGc/pkcs11: No such file or directory\ntshark: There are no interfaces on which a capture can be done\n"
希望能帮助你!