为什么strip()修复了这个pexpect脚本?

时间:2011-05-26 01:44:32

标签: regex python expect pexpect

我有一个对象。

这个对象有一个connect()方法,可以产生一个pexpect进程。

产生的过程是自定义串行接口。启动时,此工具会打印一系列要连接的串行设备,如下所示:

libftdi device (0): A6005jpt
libftdi device (1): acFX9DQf
Serial device (a) : /dev/cu.Bluetooth-PDA-Sync
Select a device by its letter (^D to abort): 

我的connect()根据给定的devicename确定要传递的号码(例如'acFX9DQf'):( self.connection是pexpect spawn)

USBSERIAL_DEVICE_NAME = "acFX9DQf"    

try:
    while self.connection.expect(['libftdi device \(([0-9])\): (.*)','Serial device']) == 0:
        if self.connection.match.group(2).strip() == USBSERIAL_DEVICE_NAME:
            # do stuff
except:
    # do stuff

现在,我的问题是我在主逻辑中多次connect() / kill()这个过程,有时,其中一个时间,connect()决定抛出一个pexpect.TIMEOUT异常,意外。

例如,当我将以下调试语句添加到我的逻辑中时,如下所示:

USBSERIAL_DEVICE_NAME = "acFX9DQf"

try:
    while self.connection.expect(['libftdi device \(([0-9])\): (.*)','Serial device'], timeout=10) == 0:
        print "MATCHED A DEVICE LINE!"
        if self.connection.match.group(2).strip() == USBSERIAL_DEVICE_NAME:
            print "MATCHED THE DESIRED USBSERIAL..."

...我为connect()的多次调用获得了此输出:

libftdi device (0): A6005jpt
MATCHED A DEVICE LINE!
libftdi device (1): acFX9DQf
MATCHED A DEVICE LINE!
MATCHED THE DESIRED USBSERIAL...
Serial device (a) : /dev/cu.Bluetooth-PDA-Sync
Select a device by its letter (^D to abort): 1

...然后,我的一个connect()电话会意外地发生....

libftdi device (0): A6005jpt
MATCHED A DEVICE LINE!
libftdi device (1): acFX9DQf
Serial device (a) : /dev/cu.Bluetooth-PDA-Sync
Select a device by its letter (^D to abort): MATCHED A DEVICE LINE!

<<EXCEPTION>>

但是,如果我修改我的代码:

try:
    while self.connection.expect(['libftdi device \(([0-9])\): (.*)','Serial device'], timeout=10) == 0:
        devicename = self.connection.match.group(2).strip()
        if devicename == USBSERIAL_DEVICE_NAME:
            # do stuff

我的问题消失了!我可以反复运行它,不会出现任何问题 - 没有例外,没有任何问题。

所以在这里发生了什么事?我甚至不确定从哪里开始解决这个问题。

1 个答案:

答案 0 :(得分:1)

我猜你得到TIMEOUT例外。基于“匹配的设备线!”的位置消息在输出中,我的假设是spawn实例在测试匹配时有多行。当pexpect编译正则表达式时,它sets re.DOTALL,因此.*包括换行符和附加行。这导致针对USBSERIAL_DEVICE_NAME的测试失败并且循环继续其下一次迭代。下一次调用expect会因为没有其他输入而导致超时。

要解决此问题,您可以传入自己编译的正则表达式(缺少re.DOTALL标志)或更改.*,以使其显式与换行符不匹配(例如{{1} })。

至于为什么在变量中存储匹配的组似乎可以解决问题,我只能猜测这会引入一个微妙的时序更改,阻止调用\S*一次接收多行输入。