Search code examples
tclexpectqemu

How to copy from spawned expect process into file?


I have a Raspberry Pi image running via a qemu emulator, which I interact with via expect.

I'm trying to capture the output from a particular command within the emulator, and save it to a file on the host.

Being a beginner with Tcl, I read through the manual and had a go at this. The "test.out" file is created but contains only a newline, while "Hello world!" appears on the console.

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

Solution

  • This answer was very useful in finding a solution. However, for long outputs you need to account for the buffer filling up.

    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 }
    }
    

    If the line length can exceed the buffer size then something more complicated is needed.

    For some reason, the line endings are \r\r\n, but that can be fixed with a sed.

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