在提示之前如何监视孩子的输出?

时间:2019-11-06 12:08:32

标签: python subprocess pexpect

这是一个慢速应用程序的示例代码。 (想象一下Linux的启动)这是应该控制的DUT。

#linux.py

import time

print('Loading kernel ......')
time.sleep(0.5)
print('Loading foo  [  OK  ]')
time.sleep(0.5)
print('Loading bar  [  OK  ]')
time.sleep(0.5)
input('login> ')

我想通过pexpect python脚本进行控制,如下所示。

# controller.py

import pexpect
import sys

pybin = sys.executable

command = pybin + ' linux.py' 

p = pexpect.spawn(command)
p.expect('> ', timeout = 5)
print(p.before.decode(), end='')
print(p.match.group(0).decode())
p.sendline('')

可以,但是在完全启动之前,我无法获得“ Linux.py's” 引导的控制台输出。我的意思是,登录提示之前我没有得到反馈。想象一下,启动过程中出现错误。上面的脚本会因超时异常而失败。

我的目标

要监视子进程并在等待提示时打印其输出。怎么办?

1 个答案:

答案 0 :(得分:0)

解决方案1 ​​

我发现了一个基于this问题的简单方法

# controller.py

import pexpect
import sys

pybin = sys.executable

command = pybin + ' linux.py' 

p = pexpect.spawn(command)
while True:
    # The return value is the index of the matched string
    i=p.expect(['> ', '\n'], timeout = 5)
    print(p.before.decode(), end='')
    print(p.match.group(0).decode(), end='')
    if i==0:
        break
print()
p.sendline('')

关键是要等待多个“期望的字符串” 。然后确定哪个是真正的提示,哪个是行尾。如果错误以换行符终止,则此解决方案有效。

解决方案2

另一种方法是使用较小的超时并打印before字符串的适当块:

# controller.py

import pexpect
import sys

pybin = sys.executable

command = pybin + ' linux.py' 

p = pexpect.spawn(command)
timeout_cnt = 0
print_idx = 0
while True:
    try:
        i=p.expect('> ', timeout = 1)
        # prompt has arrived
        break
    except pexpect.TIMEOUT:
        timeout_cnt += 1
        if timeout_cnt>30:
            # A real timeout has occured
            raise
    finally:        
        print(p.before.decode()[print_idx:], end='')
        print_idx = len(p.before.decode())
print(p.match.group(0).decode(), end='')
print()
p.sendline('')