You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将expect操作qemu树莓派时的命令输出保存到宿主机文件?

问题原因

  • expect默认会将spawn进程的所有输出同步打印到控制台,所以命令输出直接显示在终端,没有被捕获
  • gets $ftty仅单次读取一行内容,发送echo命令后第一行读到的是命令本身的输入回显,还没拿到实际的输出内容,写入文件的是空行,所以只有一个换行符
  • 读取输出的时机早于命令输出返回时间,导致内容读取不完整

修正方案

推荐直接使用expect内置的输出捕获逻辑,实现更稳定:

spawn qemu-system-arm --serial mon:stdio ...

# 关闭spawn进程输出到控制台的默认行为
log_user 0

expect {
    "login:" { send "pi\r" }
}
expect {
    "Password:" { send "raspberry\r" }
}
expect "pi@raspberrypi"

set fsignature [open "test.out" w]

send "echo 'Hello world!'\r"
# 等待命令执行完成返回提示符,匹配区间内的所有输出存在$expect_out(buffer)
expect "pi@raspberrypi"
# 过滤命令回显、控制字符和提示符,提取实际输出内容
regexp {echo 'Hello world!'\s+(.*?)\s+pi@raspberrypi} $expect_out(buffer) match cmd_output
puts $fsignature $cmd_output

close $fsignature

send "sudo shutdown now\r"
wait

如果需要使用exp_open通道方式读取,修改后的代码如下:

spawn qemu-system-arm --serial mon:stdio ...

log_user 0

expect {
    "login:" { send "pi\r" }
}
expect {
    "Password:" { send "raspberry\r" }
}
expect "pi@raspberrypi"

set ftty [exp_open -leaveopen]
set fsignature [open "test.out" w]

send "echo 'Hello world!'\r"
expect "pi@raspberrypi"
# 读取通道内所有返回内容
set all_output [read $ftty]
regexp {echo 'Hello world!'\s+(.*?)\s+pi@raspberrypi} $all_output match cmd_output
puts $fsignature $cmd_output

close $ftty
close $fsignature

send "sudo shutdown now\r"
wait

关键改动说明

  • 新增log_user 0配置,关闭spawn进程输出到控制台的默认行为,所有输出仅流入expect缓冲区或exp_open打开的通道
  • 先等待命令执行完成、提示符返回后再读取输出,避免内容读取不完整
  • 通过正则表达式过滤掉命令回显、控制字符和提示符,仅保留需要的命令执行结果

内容的提问来源于stack exchange,提问作者OrangeDog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 19:27:04