Example—A Dumb Terminal Emulator

The following script creates two text widgets that work like primitive terminals. One allows interaction with a telnet process and the other with a shell. The script has a bind command to pass user keystrokes to the processes and an expect_background command to handle the output of the two processes.

Notice that the expect_background command discards \r characters since output lines ordinarily end with \r\n but the text widget only expects \n as its line terminator. No further intelligence is provided for more sophisticated emulation. For example, absolute cursor motion is not supported. Nonprintable characters appear on the screen as hex escapes.

# start a shell and text widget for its output
spawn $env(SHELL)
set shell $spawn_id
text .shell -relief sunken -bd 1
pack .shell


# start a telnet and a text widget for its output
spawn telnet
set telnet $spawn_id
text .telnet  -relief sunken -bd 1
pack .telnet

expect_background {
    -i $telnet -re "\[^\x0d]+" {
        .telnet insert end $expect_out(0,string)
        .telnet yview -pickplace insert
    }
    -i $shell -re "\[^\x0d]+" {
        .shell insert end $expect_out(0,string)
        .shell yview -pickplace insert
    }
    -i $any_spawn_id "\x0d" {
        # discard \r
    }
}

bind Text    <Any-Enter>    {focus %W}
bind .telnet <Any-KeyPress> {exp_send −i $telnet "%A"}
bind .shell  <Any-KeyPress> {exp_send −i $shell  "%A"}

Get Exploring Expect now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.