首页 > 解决方案 > 我如何找出是什么在缓冲从 qemu 到 pexpect 的通信?

问题描述

我有一个 Python2 程序,它使用 FreeBSD 映像运行 qemu。
expect()ing 行输出工作。
但是,expect()没有终止其行的 ing 输出(例如在等待类似 的提示时login:)不会,这会超时。

我怀疑 qemu 和我的程序之间的通信中的某些东西正在做行缓冲,但是我如何找出它们中的哪一个呢?我能想到的候选人:

作为参考,这里是精简的代码(包括下载和解包,如果有人想玩的话):

#! /usr/bin/env python2

import os
import pexpect
import re
import sys
import time

def run(cmd):
    '''Run command, log to stdout, no timeout, return the status code.'''
    print('run: ' + cmd)
    (output, rc) = pexpect.run(
        cmd,
        withexitstatus=1,
        encoding='utf-8',
        logfile=sys.stdout,
        timeout=None
        )
    if rc != 0:
        print('simple.py: Command failed with return code: ' + rc)
        exit(rc)


download_path = 'https://download.freebsd.org/ftp/releases/VM-IMAGES/12.0-RELEASE/amd64/Latest'
image_file = 'FreeBSD-12.0-RELEASE-amd64.qcow2'
image_file_xz = image_file + '.xz'

if not os.path.isfile(image_file_xz):
    run('curl -o %s %s/%s' % (image_file_xz, download_path, image_file_xz))

if not os.path.isfile(image_file):
    # Reset image file to initial state
    run('xz --decompress --keep --force --verbose ' + image_file_xz)

#cmd = 'qemu-system-x86_64 -snapshot -monitor none -display curses -chardev stdio,id=char0 ' + image_file
cmd = 'qemu-system-x86_64 -snapshot -nographic ' + image_file
print('interact with: ' + cmd)
child = pexpect.spawn(
    cmd,
    timeout=90, # FreeBSD takes roughly 60 seconds to boot
    maxread=1,
    )
child.logfile = sys.stdout

def expect(pattern):
    result = child.expect([pexpect.TIMEOUT, pattern])
    if result == 0:
        print("timeout: %d reached when waiting for: %s" % (child.timeout, pattern))
        exit(1)
    return result - 1

if False:
    # This does not work: the prompt is not visible, then timeout
    expect('login: ')
else:
    # Workaround, tested to work:
    expect(re.escape('FreeBSD/amd64 (freebsd)')) # Line before prompt
    time.sleep(1) # MUCH longer than actually needed, just to be safe

child.sendline('root')

# This will always time out, and terminate the script
expect('# ')
print('We want to get here but cannot')

标签: qemupexpect

解决方案


推荐阅读