pexpect 超时未生效,仅使用默认的 30 秒

9 投票
3 回答
35004 浏览
提问于 2025-04-16 01:52

我正在尝试执行一个比较长的操作,但使用pexpect库时,即使我设置了超时时间,超时异常触发的时间似乎没有变化。以下是我的代码:

child = pexpect.spawn('scp file user@:/temp', timeout=300)

whichMatched = child.expect(['(?i)Password','Are you sure you want to continue connecting (yes/no)?'], timeout=300)

异常信息显示超时时间是30秒,这是默认设置。

after: <class 'pexpect.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 6222
child_fd: 4
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1

3 个回答

2

我觉得@darricks说错了。这里有个例子可以说明,即使在调用spawn()的时候没有指定超时时间,expect()的超时参数还是会被遵守。

test_pexpect.py

#! /usr/bin/env python

import pexpect
child = pexpect.spawn('sleep 50')
i = child.expect(['.* password:', 'Are you sure you want to continue connecting'], timeout=40)

这是来自Linux的输出。test_pexpect.py的输出中显示“timeout: 30”。这只是显示了spawn()的超时时间。但是,底部的time输出显示脚本在40秒时结束。所以expect()的超时时间是被遵守的。

$ time test_pexpect.py
Traceback (most recent call last):
  File "./test_pexpect.py", line 5, in <module>
    i = child.expect(['.* password:', 'Are you sure you want to continue connecting'], timeout=40)
  File "/usr/rx30/musl/Python-2.7.14.install/lib/python2.7/site-packages/pexpect/spawnbase.py", line 341, in expect
    timeout, searchwindowsize, async_)
  File "/usr/rx30/musl/Python-2.7.14.install/lib/python2.7/site-packages/pexpect/spawnbase.py", line 369, in expect_list
    return exp.expect_loop(timeout)
  File "/usr/rx30/musl/Python-2.7.14.install/lib/python2.7/site-packages/pexpect/expect.py", line 119, in expect_loop
    return self.timeout(e)
  File "/usr/rx30/musl/Python-2.7.14.install/lib/python2.7/site-packages/pexpect/expect.py", line 82, in timeout
    raise TIMEOUT(msg)
pexpect.exceptions.TIMEOUT: Timeout exceeded.
<pexpect.pty_spawn.spawn object at 0xf76b30ac>
command: /bin/sleep
args: ['/bin/sleep', '50']
buffer (last 100 chars): ''

after: <class 'pexpect.exceptions.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 31968
child_fd: 5
closed: False
timeout: 30
delimiter: <class 'pexpect.exceptions.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
searcher: searcher_re:
    0: re.compile('.* password:')
    1: re.compile('Are you sure you want to continue connecting')

real    0m40.235s
user    0m0.053s
sys     0m0.043s
$
8

我刚刚试了下面的代码,似乎可以正常工作:

child.timeout=300
child.expect("...")

7

如果你在 .spawn 调用中只设置超时时间,它似乎可以正常工作。但是,如果你在 .expect 调用中单独使用 timeout=300 是无法覆盖之前设置的超时时间的。

撰写回答