0

我必须捕获tshark -D使用 python的输出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。为什么会给出这样的结果?

4

3 回答 3

2

要获取子进程是否在 stdout 或 stderr 上打印的所有输出,您可以使用stderr=STDOUTand subprocess.check_output

from subprocess import check_output, STDOUT

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

tshark手册说:

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

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

于 2014-03-28T12:59:27.263 回答
0

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

如果您在名为“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 上。正确的方式应该是bwlow:

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"

希望能帮到你!

于 2014-03-28T06:17:43.790 回答
0

tshark -D总是打印到标准错误。在情况 #1 中,由于您没有捕获 stderr,因此会将其打印到您的控制台。

在情况 #2 中,由于您同时捕获了 stdout 和 stderr,因此 stdout ==> '' 和 stderr ==> 输出。

于 2014-03-28T06:03:17.763 回答