如何从生成的期望进程复制到文件中?

How to copy from spawned expect process into file?

我通过 qemu 模拟器有一个 Raspberry Pi 图像 运行,我通过 expect 与之交互。

我正在尝试捕获模拟器中特定命令的输出,并将其保存到主机上的文件中。

作为 Tcl 的初学者,我通读了手册并试了一下。 “test.out”文件已创建,但仅包含一个换行符,而“Hello world!”出现在控制台上。

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

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"
puts $fsignature [gets $ftty]
expect "pi@raspberrypi"

send "sudo shutdown now\r"
wait

我不熟悉exp_open。我通常会推荐这样的东西来捕获命令输出:

set prompt {pi@raspberrypi}
set cmd {echo 'hello world'}
send "$cmd\r"
expect -re "$cmd\r\n(.*)\r\n$prompt"
puts $fsignature $expect_out(1,string)

提取命令输出可能很棘手,因为发送的命令(通常)会显示并包含在预期输出中。这假定您指定的提示首先出现在其行中。

对于寻找解决方案非常有用。 但是,对于长输出,您需要考虑缓冲区已满。

set fd [open "test.out" w]
send "cat large_output\r"
expect {
    -re {cat large_output[\r\n]+}  { log_user 0; exp_continue }
    -ex "\n" { puts -nonewline $fd $expect_out(buffer); exp_continue }
    -re $prompt { log_user 1; close $fd }
}

如果行长度可以超过缓冲区大小,则需要更复杂的东西。

出于某种原因,行尾是 \r\r\n,但这可以用 sed 来修复。

sed -i 's/\r//g' test.out