What Expect Solves
Expect, created by Don Libes on top of Tcl, automates interaction with programs that expect a human at a terminal — logins, ftp, telnet, passwd, serial-port modems, or any CLI that prompts for input — by spawning a child process under a pseudo-terminal and scripting the back-and-forth dialogue that would otherwise require a person typing responses to prompts.
Cricket analogy: Expect scripting a login prompt is like a translator standing between two people who speak different pre-agreed signals — it 'spawns' the conversation and responds to each prompt exactly as a twelfth man would relay instructions from the dressing room to the field.
spawn, send, and expect Basics
The three core Expect commands are spawn (start a subprocess and attach it to a pseudo-terminal, e.g. spawn ssh user@host), expect (block until output matching a pattern appears, e.g. expect "password:"), and send (write text to the spawned process's stdin, e.g. send "$mypassword\r") — together they let a script drive an entire interactive session exactly as a human would type responses.
Cricket analogy: The spawn/expect/send cycle is like a captain (spawn) sending a fielder out, waiting for the umpire's specific signal (expect) before reacting, then relaying the next instruction (send) — a repeating loop of watch-then-respond.
Pattern Matching with expect
expect patterns can be plain strings, glob patterns, or full regular expressions via -re, and multiple alternatives are matched together with a single call: expect { "password:" { send "$pw\r" } "yes/no" { send "yes\r"; exp_continue } timeout { puts "login stalled"; exit 1 } }, where exp_continue re-enters the same expect block to keep matching further prompts without writing a new expect statement.
Cricket analogy: Matching several alternative patterns in one expect block is like a fielding captain having pre-set responses for every likely outcome of a delivery — dot ball, single, boundary — each triggering a different pre-agreed field adjustment.
#!/usr/bin/expect -f
set timeout 20
set host [lindex $argv 0]
set user [lindex $argv 1]
set pw [lindex $argv 2]
spawn ssh -o StrictHostKeyChecking=no $user@$host
expect {
"password:" {
send "$pw\r"
exp_continue
}
"yes/no" {
send "yes\r"
exp_continue
}
"$ " {
# shell prompt reached; login succeeded
}
timeout {
puts "ERROR: login timed out after 20s"
exit 1
}
eof {
puts "ERROR: connection closed unexpectedly"
exit 1
}
}
send "uptime\r"
expect "$ "
puts $expect_out(buffer)
send "exit\r"
expect eofTimeouts, EOF, and Robust Control Flow
Robust Expect scripts always guard against timeout and eof as explicit branches inside every expect block, because a spawned process that hangs, crashes, or closes its connection otherwise leaves the script blocked forever with no error reported; set timeout 20 sets a default in seconds applied to subsequent expect calls, and per-block timeout/eof patterns let the script fail fast with a clear diagnostic instead of hanging a CI pipeline indefinitely.
Cricket analogy: Guarding every expect block with a timeout branch is like a third umpire enforcing a strict time limit on DRS reviews so the match doesn't stall indefinitely waiting for a decision that never comes.
Forgetting timeout and eof branches is the single most common cause of Expect scripts hanging forever in CI pipelines — a spawned ssh session waiting on an unexpected host-key prompt or a crashed remote shell will otherwise block the calling script (and any automation depending on it) with no error and no exit, silently consuming a CI runner slot.
Interact Mode and Common Pitfalls
After automation completes its scripted portion, interact hands control of the spawned process back to the real terminal user, letting a script do the tedious login and setup automatically and then drop the human into a live interactive session — useful for jump-host automation where a script authenticates through several hops before handing off a genuine shell to the operator.
Cricket analogy: interact handing control back to the human after automated setup is like a substitute fielder warming up in place of an injured player, then handing the position back once the original player is ready to take over.
interact accepts its own pattern-action pairs too, so you can keep scripted reactions active even while the human is typing — for example interact { "~exit" { send "logout\r"; return } } lets an operator type a custom escape sequence to end the session cleanly instead of relying on the shell's own exit command.
- Expect drives interactive CLI programs by spawning them under a pseudo-terminal and scripting expected prompts and responses.
spawn,expect, andsendform the core loop: start a process, wait for a pattern, write a response.expectblocks can match multiple alternative patterns at once, including glob and-reregex patterns.exp_continuere-enters the current expect block to handle further prompts without duplicating expect statements.- Every expect block should guard against
timeoutandeofto avoid hanging forever on a stuck or dropped connection. interacthands control from the script back to a live human, useful for automated login followed by manual work.- Missing timeout/eof handling is the most common cause of Expect scripts hanging CI pipelines indefinitely.
Practice what you learned
1. What is the primary purpose of the Expect extension for Tcl?
2. In `expect { "password:" { send "$pw\r" } timeout { exit 1 } }`, what happens if neither pattern matches before the timeout elapses?
3. What does `exp_continue` do inside an expect block?
4. What does the `interact` command do?
5. Why is omitting timeout and eof branches from expect blocks considered risky?
Was this page helpful?
You May Also Like
Tcl for EDA and Scripting Tools
Understand why Tcl became the standard scripting glue for EDA tools like Synopsys and Cadence, and how to write scripts that drive simulation, synthesis, and place-and-route flows.
Packaging Tcl Applications
Learn how to structure, package, and distribute Tcl/Tk applications using Tcl Modules, starkits/starpacks, and standalone executables.
Tcl and C Extension Basics
Understand how to extend Tcl with compiled C code — writing custom commands, managing the Tcl_Obj type system, and building a loadable extension.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics