Как контролировать выход ребенка перед Promt? - PullRequest
0 голосов
/ 06 ноября 2019

Вот пример кода медленного приложения. (Представьте себе загрузку 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 голосов
/ 06 ноября 2019

Решение 1

Я нашел простой способ, основанный на этом вопросе

# 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('')
...