"expect_out(buffer) has the content of the previous send"

The titular quote is something newcomers to Expect often say--as one of Expect's frequently-made mistakes, it indicates a misconception or two.

This explanation deserves its own Wiki page: Expect is organized in terms of a dialogue. It does not have a direct notion of "the content of the previous send"; instead, we all have the expectation that, after a command is sent, what appears before the next prompt is the result of that command. That's a convention, though. From Expect's perspective, it's all just characters going back and forth, with no privileged concept of "command", "prompt", or so on.

Let's do a simple example: what do you expect from

    set prompt {$ }

    spawn ssh $user@$host
    expect "Password: "
    send $password\r
    expect $prompt
    send ls\r
    puts "The output is '$expect_out(buffer)'."

? You'll probably see something like the $host logon message.

To achieve what people think they want, it's necessary to write instead

    spawn ssh $user@$host
    expect "Password: "
    send $password\r
    expect $prompt
    send ls\r
    expect $prompt
    puts "The output is '$expect_out(buffer)'."

Do you see the difference?


It's sometimes useful to

    expect *            ; # Receive *anything* returned immediately. 

My experience has been this is hardly ever useful - it means "match on anything - including nothing" and usually returns nothing. But it does it very quickly. RJ

and/or

    expect timeout      ; # Receive everything returned up to $timeout seconds.

when one "just wants the answer".

Also, note that $expect_out(buffer) doesn't really hold what people want; it typically needs to be filtered down at least to eliminate the prompt.

Also be aware of the "match_max <max buffer size>" expect buffer size. if you do not get all the response you expect then you should probably increase the size.


"How to access the result of a remote command in Expect" makes somewhat different computations to achieve similar results.