我有一个对象。
这个对象有一个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
我的问题消失了!我可以反复运行它,不会出现任何问题 - 没有例外,没有任何问题。
所以在这里发生了什么事?我甚至不确定从哪里开始解决这个问题。
答案 0 :(得分:1)
我猜你得到TIMEOUT
例外。基于“匹配的设备线!”的位置消息在输出中,我的假设是spawn
实例在测试匹配时有多行。当pexpect编译正则表达式时,它sets re.DOTALL
,因此.*
包括换行符和附加行。这导致针对USBSERIAL_DEVICE_NAME
的测试失败并且循环继续其下一次迭代。下一次调用expect
会因为没有其他输入而导致超时。
要解决此问题,您可以传入自己编译的正则表达式(缺少re.DOTALL
标志)或更改.*
,以使其显式与换行符不匹配(例如{{1} })。
至于为什么在变量中存储匹配的组似乎可以解决问题,我只能猜测这会引入一个微妙的时序更改,阻止调用\S*
一次接收多行输入。