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

发布于 2024-11-09 22:09:00 字数 2102 浏览 4 评论 0原文

我有一个对象。

该对象有一个 connect() 方法,该方法会生成一个 pexpect 进程。

生成的进程是一个自定义串行接口。启动时,该工具会打印要连接的串行设备的菜单,如下所示:

libftdi device (0): A6005jpt
libftdi 设备 (1):acFX9DQf
串行设备(a):/dev/cu.Bluetooth-PDA-Sync
通过字母选择设备(^D 表示中止): 

我的 connect() 根据给定的设备名称(例如“acFX9DQf”)确定要传递的数字:(self.connection 是pexpect 生成)

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() 进程,有时,其中一次,连接()决定意外地抛出 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
匹配设备系列!
libftdi 设备 (1):acFX9DQf
匹配设备系列!
匹配所需的 USB 串口...
串行设备(a):/dev/cu.Bluetooth-PDA-Sync
按字母选择设备(^D 表示中止):1

...然后,我的一个 connect() 调用将意外地执行...

libftdi device ( 0): A6005jpt
匹配设备系列!
libftdi 设备 (1):acFX9DQf
串行设备(a):/dev/cu.Bluetooth-PDA-Sync
按字母选择设备(^D 中止):匹配设备线!

<>

但是,如果我将代码修改为:

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

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

那么这里到底发生了什么?我什至不知道从哪里开始解决这个问题。

I have an object.

This object has a connect() method which spawns a pexpect process.

The process that's spawned is a custom serial interface. On launch, this tool prints a menu of serial devices to connect to, like so:

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): 

My connect() determines which number to pass based on a given devicename (e.g. 'acFX9DQf'): (self.connection is the 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

Now, my problem is that I connect()/kill() the process multiple times in my main logic and sometimes, one of those times, connect() decides to throw a pexpect.TIMEOUT exception, unexpectedly.

For example, when I add the following debug statements to my logic, like so:

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..."

...I get this output for many calls of 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

...then, one of my connect() calls will unexpectedly do....

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>>

But, if I revise my code to this:

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

My problems go away! I can run it repeatedly and no problems will occur - no exceptions, no nothin'.

So wot in the heck is going on here? I'm not even sure where to begin with this problem.

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

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

发布评论

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

评论(1

柳若烟 2024-11-16 22:09:00

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

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

至于为什么将匹配的组存储在变量中似乎可以解决问题,我只能猜测这会引入微妙的时间变化,从而阻止对 expect 的调用同时接收多行输入。

I'm guessing you're getting a TIMEOUT exception. Based on where the "MATCHED A DEVICE LINE!" message is in the output, my hypothesis is that the spawn instance has multiple lines when it tests for a match. When pexpect compiles the regexes, it sets re.DOTALL, so the .* includes the newline and the additional lines. This causes the test against USBSERIAL_DEVICE_NAME to fail and the loop continues its next iteration. The next call to expect blocks because there is no additional input and you get a timeout.

To fix this, you can pass in your own compiled regexes (which will lack the re.DOTALL flag) or change the .* so it explicitly doesn't match the newline (e.g. \S*).

As for why storing the matched group in a variable seems to fix things, I can only guess this introduces a subtle timing change that prevents the call to expect from receiving multiple lines of input at once.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文