qemu - 我如何找出是什么在缓冲从 qemu 到 pexpect 的通信?
问题描述
我有一个 Python2 程序,它使用 FreeBSD 映像运行 qemu。
expect()
ing 行输出工作。
但是,expect()
没有终止其行的 ing 输出(例如在等待类似 的提示时login:
)不会,这会超时。
我怀疑 qemu 和我的程序之间的通信中的某些东西正在做行缓冲,但是我如何找出它们中的哪一个呢?我能想到的候选人:
- FreeBSD 本身。我发现这不太可能,它会在交互运行时显示提示,并且 qemu 的
-nographics
选项不应该对模拟的 VM 产生影响(但我可能错了)。 - pty 的设置中的某些内容。我对 ptys 的经验为零。如果这是问题所在,这将是 pexpect 中的一个错误,因为 pexpect 正在设置 pty。
- 预期中的错误。
- 我自己的脚本中有一些东西......但我不知道那可能是什么。
作为参考,这里是精简的代码(包括下载和解包,如果有人想玩的话):
#! /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')
解决方案
推荐阅读
- python - 为什么 elasticsearch python parallel_bulk 使用这么多内存?
- spring-boot - 如何让日志文件删除与 spring-boot-starter-log4j2 一起使用?
- java - 安卓无法删除文件
- java - Maven Archetypes 上的速度反射:从 Json 获取数据
- asp.net-core - ASP.Core ODataControllers 无法识别“按键获取”操作
- html - 将特定属性传递给选定的子级
- html - 垂直对齐表格中的图像
- sql - 使用 windows 函数 + 分区计算 2 列的百分比
- c# - 根据列列表动态选择
- python - 如何使用python使用firestore字段增量?