首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解析pexpect输出

解析pexpect输出
EN

Stack Overflow用户
提问于 2013-11-25 08:12:40
回答 1查看 15.4K关注 0票数 5

我正在尝试实时解析程序块缓冲的输出,这意味着输出在进程结束之前不可用。我需要的只是逐行解析,过滤和管理输出中的数据,因为它可能会运行几个小时。

我尝试过使用subprocess.Popen()来捕获输出,但是,正如您可能猜到的那样,Popen无法管理这种行为,它会一直缓冲到进程结束。

代码语言:javascript
复制
from subprocess import Popen, PIPE

p = Popen("my noisy stuff ", shell=True, stdout=PIPE, stderr=PIPE)
for line in p.stdout.readlines():
    #parsing text and getting data

因此,我找到了pexpect,它实时打印输出,因为它将stdout视为文件,或者我甚至可以做一个肮脏的把戏,打印出一个文件并在函数外部解析它。但好吧,它太脏了,即使对我来说也是如此;)

代码语言:javascript
复制
import pexpect
import sys

pexpect.run("my noisy stuff", logfile=sys.stdout)

但我想这应该是一种更好的pythonic方式,只需像子进程一样管理stdout即可。Popen做到了。我该怎么做呢?

编辑:

运行J.F. proposal:

这是一个故意错误的审计,大约需要25秒。停下来。

代码语言:javascript
复制
from subprocess import Popen, PIPE

command = "bully mon0 -e ESSID -c 8 -b aa:bb:cc:dd:ee:00 -v 2"

p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE)

for line in iter(p.stdout.readline, b''):
    print "inside loop"
    print line

print "outside loop"
p.stdout.close()
p.wait()


#$ sudo python SCRIPT.py
                                ### <= 25 secs later......
# inside loop
#[!] Bully v1.0-21 - WPS vulnerability assessment utility

#inside loop
#[!] Using 'ee:cc:bb:aa:bb:ee' for the source MAC address

#inside loop
#[X] Unable to get a beacon from the AP, possible causes are

#inside loop
#[.]    an invalid --bssid or -essid was provided,

#inside loop
#[.]    the access point isn't on channel '8',

#inside loop
#[.]    you aren't close enough to the access point.

#outside loop

改为使用此方法: EDIT:由于输出中存在较大的延迟和超时,我不得不修改子对象,并添加了一些hack,因此最终代码如下所示

代码语言:javascript
复制
import pexpect

child = pexpect.spawn(command)
child.maxsize = 1  #Turns off buffering
child.timeout = 50 # default is 30, insufficient for me. Crashes were due to this param.
for line in child:
    print line,

child.close()

返回相同的输出,但它实时打印行。所以..。已解决的感谢@J.F. Sebastian

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-25 08:37:21

.readlines()读取所有行。难怪您在子流程结束之前看不到任何输出。只要子进程刷新其标准输出缓冲区,您就可以使用.readline()逐行读取:

代码语言:javascript
复制
from subprocess import Popen, PIPE

p = Popen("my noisy stuff", stdout=PIPE, bufsize=1)
for line in iter(p.stdout.readline, b''):
    # process line
    ..
p.stdout.close()
p.wait()

如果您已经有了pexpect,那么您可以使用它来解决块缓冲问题:

代码语言:javascript
复制
import pexpect

child = pexpect.spawn("my noisy stuff", timeout=None)
for line in child: 
    # process line
    ..
child.close()

另请参阅我在评论中链接的问题中的stdbuf, pty -based solutions

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20182827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档