Python 2.6 问题:从 tcpdump 子进程捕获输出

发布于 2024-11-06 22:24:05 字数 1553 浏览 3 评论 0原文

我正在尝试从 Python 捕获 tcpdump/grep 管道的输出。我在 Mac OS 10.6.7 上使用 Python 2.6。

当我使用 dmesg/grep 尝试时,调用者按预期接收来自子进程的输出。

当我使用 tcpdump/grep 尝试时, select 永远不会返回任何内容。

我做错了什么?

#! /usr/bin/python

def tcpdump():
    import subprocess, fcntl, os


    # This works

#   cmd1 = ['sudo', 'dmesg']
#   cmd2 = ['grep', '-E', '.*']


    # This doesn't work

    # sudo tcpdump -i en0 -n -s 0 -w - | grep -a -o -E "Host\: .*|GET \/.*"
    cmd1 = ['sudo', 'tcpdump', '-i', 'en0', '-n', '-s', '0', '-w', '-']
    cmd2 = ['grep', '-a', '-o', '-E', 'Host\: .*|GET \/.*']


    p1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE)
    p2 = subprocess.Popen(cmd2, stdout=subprocess.PIPE, stdin=p1.stdout)

    # set stdout file descriptor to nonblocking
    flags = \
    fcntl.fcntl(p2.stdout.fileno(), fcntl.F_GETFL)

    fcntl.fcntl(p2.stdout.fileno(), fcntl.F_SETFL, (flags | os.O_NDELAY | os.O_NONBLOCK))

    return p2


def poll_tcpdump(proc):
    import select

    txt = None

    while True:

        # wait 1/10 of a second and check whether proc has written anything to stdout
        readReady, _, _ = select.select([proc.stdout.fileno()], [], [], 0.1)

        if not len(readReady):
            break

        for line in iter(proc.stdout.readline, ""):

            if txt is None:
                txt = ''

            txt += line

        break

    return txt


proc = tcpdump()

while True:
    text = poll_tcpdump(proc)

    if text:
        print '>>>> ' + text

I am trying to capture the output of a tcpdump/grep pipeline from Python. I am using Python 2.6 on Mac OS 10.6.7.

When I try it with dmesg/grep, the caller receives output from the subprocesses, as expected.

When I try it with tcpdump/grep, select never returns anything.

What am I doing wrong?

#! /usr/bin/python

def tcpdump():
    import subprocess, fcntl, os


    # This works

#   cmd1 = ['sudo', 'dmesg']
#   cmd2 = ['grep', '-E', '.*']


    # This doesn't work

    # sudo tcpdump -i en0 -n -s 0 -w - | grep -a -o -E "Host\: .*|GET \/.*"
    cmd1 = ['sudo', 'tcpdump', '-i', 'en0', '-n', '-s', '0', '-w', '-']
    cmd2 = ['grep', '-a', '-o', '-E', 'Host\: .*|GET \/.*']


    p1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE)
    p2 = subprocess.Popen(cmd2, stdout=subprocess.PIPE, stdin=p1.stdout)

    # set stdout file descriptor to nonblocking
    flags = \
    fcntl.fcntl(p2.stdout.fileno(), fcntl.F_GETFL)

    fcntl.fcntl(p2.stdout.fileno(), fcntl.F_SETFL, (flags | os.O_NDELAY | os.O_NONBLOCK))

    return p2


def poll_tcpdump(proc):
    import select

    txt = None

    while True:

        # wait 1/10 of a second and check whether proc has written anything to stdout
        readReady, _, _ = select.select([proc.stdout.fileno()], [], [], 0.1)

        if not len(readReady):
            break

        for line in iter(proc.stdout.readline, ""):

            if txt is None:
                txt = ''

            txt += line

        break

    return txt


proc = tcpdump()

while True:
    text = poll_tcpdump(proc)

    if text:
        print '>>>> ' + text

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最美不过初阳 2024-11-13 22:24:05

尝试

cmd2 = ['grep', '--line-buffered', '-a', '-o', '-E', 'Host\: .*|GET \/.*']

Try

cmd2 = ['grep', '--line-buffered', '-a', '-o', '-E', 'Host\: .*|GET \/.*']
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文