使用子进程调用tshark命令

问题描述

我正在尝试使用以下命令在Python中读取.pcapng

tshark_out = subprocess.getoutput('tshark -r USB.pcapng')

但是,我的代码创建了一个错误

UnicodeDecodeError:“ ascii”编解码器无法解码位置30的字节0xe2:序数不在范围(128)中

我可以通过在命令中进行转换来解决此问题,还是需要通过更改Python脚本来解决此问题?

解决方法

您正在Python3中使用旧版Python2子命令(请参见subprocess.getoutput docs

部分问题是您正在使用getoutput将字节对象转换为隐式字符串。 0xe2为226,大于ASCII的128范围。 相反,您应该将stdout和stderr作为字节对象获取,并在以后的命令中进行转换。例如:

# captures the output for 1 packet.
import subprocess as sp
cmd = sp.run(["tshark","-c","1"],stdout=sp.PIPE,stderr=sp.PIPE)
print("STDOUT:\n",cmd.stdout,"\n\nSTDERR:\n",cmd.stderr)

提供输出

STDOUT:
b'    1   0.000000 179.118.244.35.bc.googleusercontent.com \xe2\x86\x92 
192.198.128.5 TLSv1.2  105 Application Data 6c:94:cf:d8:7f:e7 \xe2\x86\x90 
e0:55:3d:71:f7:29\n' 

STDERR:
b"Capturing on 'Wi-Fi: en0'\n1 packets dropped from Wi-Fi: en0\n1 packets captured\n"

您现在有了用于stdout和stderr的字节对象。您可以使用所需的任何编码方式(例如ASCII,UTF-8)对它们进行解码,也可以直接在代码中使用它们。

您可能还想看看scapy,这是一个处理数据包的python库。

注意:此示例使用运行,但是有许多Python Popen wrappers做类似的事情。