【问题标题】:Python: piping pcap file to stdout gives errorPython:将 pcap 文件传送到标准输出会出错
【发布时间】:2025-12-04 09:10:01
【问题描述】:

我正在尝试将xz 的输出通过管道传输到自定义 python 脚本:

xz -cd file.pcap.xz | myscripy.py

但是,当脚本尝试运行此行时,我得到一个错误:

  #!/usr/bin/env python2.7
from __future__ import print_function

import pcap
import io
STDIN_ALIAS = '/proc/self/fd/0' 

pcap.pcap(io.open(STDIN_ALIAS, 'r'))

并收到错误

    pcap.pcap(io.open(STDIN_ALIAS, 'r'))
  File "pcap.pyx", line 196, in pcap.pcap.__init__
TypeError: expected string or Unicode object, _io.TextIOWrapper found

我在 Ubuntu 18.04 上并在 python 2.7 下运行。

【问题讨论】:

标签: python pipe stdout pcap


【解决方案1】:

您不能使用 Python 将数据包从文件传递到 pcap.pcap()。您正在使用的pypcap librarypcap_open_offline()pcap_create() C 函数的薄包装,并且不提供传递Python 文件对象的工具。这个包装器接受文件名或网络接口名,没有别的。

pcap_open_offline() 函数确实接受- 作为stdin 的别名,所以直接传入即可:

import pcap

sniffer = pcap.pcap('-')

【讨论】:

    【解决方案2】:

    错误消息已经告诉您发生了什么。您需要pcap() 函数的字符串,而不是文件对象。要解决此问题,请尝试

    pcap.pcap(io.open(STDIN_ALIAS, 'r').read())
    

    但我不确定这是否可行,因为您的文件可能是二进制而不是文本。在这种情况下,您可能希望使用 'rb' 而不是 'r' 标志打开,然后进行一些转换(尤其是如果您使用 Python 3 而不是 Python 2.7)。

    我看到另一个问题:您的代码不可移植,因为它取决于此:

    STDIN_ALIAS = '/proc/self/fd/0' 
    

    读取标准输入的pythonic方法如下(见Reading binary data from stdin

    import sys
    string = sys.stdin.read()
    

    【讨论】:

    • 我试过pcap.pcap(io.open(STDIN_ALIAS, 'r').read())它给出了一个错误:UnicodeDecodeError: 'utf8' codec can't decode byte 0xb2 in position 2: invalid start byte' i tried pcap.pcap(io.open(STDIN_ALIAS, 'rb').read())`它给出了一个错误:OSError: M<��: You don't have permission to capture on that device (socket: Operation not permitted)
    • 您不能将数据包传递给pcap.pcap() 类;它只接受文件名或网络接口。幸运的是,文件名- 被接受以引用标准输入。
    【解决方案3】:

    您是否尝试过升级 PyPcap 以在 Python 3 上工作?这可能会有所帮助,因为 Unicode 处理在 Python 3 上更加简洁且不易出现意外。至少在 Debian 上(可能还有派生的发行版)有适当的包可用。寻找:python3-pypcap。

    【讨论】:

    • 无法通过 apt-get 找到它们
    • 这不是 Unicode 问题,因为 pcap 根本无法传递打开的文件对象,无论如何都不能通过 Python 包装器。这适用于 Python 2 和 Python 3,库是相同的。