Python 2.6 问题:从 tcpdump 子进程捕获输出
我正在尝试从 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试
Try