Expect script explainer
Paste an Expect script and read what it would do, command by command: what it spawns, what it waits for, what it types, when it hands over to you. Then the dialogue it conducts and the findings: a password in clear text, a timeout left at the default or set to never, a pattern that matches too soon, a send without the return the program waits for, a script that ends before the program has answered. Parsed with the Tcl 8.4 engine, never run; every rule cites the expect(1) manual.
Text & utilitiesTcl reads it. 1 error, 1 warning, 4 notes.
11 lines, 9 commands. Spawns telnet. Timeout at the first expect: the default, 10 seconds. Never waits for the program to end.
The dialogue
| # | line | waits for | then types |
|---|---|---|---|
| 1 | 3 | login: | admin\r |
| 2 | 5 | Password: | •••••••• |
| 3 | 7 | > | terminal length 0\r |
| 4 | 9 | > | show running-config\r |
Command by command
- 1
#!/usr/bin/expectRuns under
/usr/bin/expect: the first line names the interpreter; to Tcl it is a comment. - 2
spawn telnet 10.0.0.1Starts
telnetwith10.0.0.1as the current process. From here, expect reads its output and send types at it. - 3
expect "login:"Waits for the program's output to match: one pattern.
login:
- 4
send "admin\r"Types
admin\rat the program, ending with a return. - 5
expect "Password:"Waits for the program's output to match: one pattern.
Password:
- 6
send "Cisco123\r"Types
Cisco123\rat the program, ending with a return. - 7
expect ">"Waits for the program's output to match: one pattern.
>
- 8
send "terminal length 0\r"Types
terminal length 0\rat the program, ending with a return. - 9
expect ">"Waits for the program's output to match: one pattern.
>
- 10
send "show running-config\r"Types
show running-config\rat the program, ending with a return.
The script, lines marked
Findings
- noteE2line 3Timeout
expect "login:"No timeout was set before this expect, so the default of 10 seconds applies (expect(1)). Slow logins and long commands need more; say what you mean with set timeout.
- noteE7line 3No timeout handler
expect "login:"4 expects wait on a pattern with no timeout handler. When the pattern does not arrive in time, expect(1) executes an implicit null action: the expect returns silently and the script carries on as if it had matched, typing commands at a program that is not where the script thinks it is. Add a timeout pattern that reports and exits.
- errorE1line 6Secret in clear text
send "Cisco123\r"A secret typed in clear text: right after a password prompt the script sends ••••••••, written in the file. Anyone who can read the script can read the password. Take it from the command line (lindex $argv), from the environment ($env(NAME)), or ask for it with stty -echo and expect_user.
- noteE3line 7Pattern that matches too soon
expect ">"A one-character pattern, >. Patterns are unanchored and match anywhere in the output, so a banner or an earlier line that contains this character ends the wait early. Match more of the prompt, and anchor a regexp with $ (expect(1) encourages it when you can describe the end of the string).
- noteE3line 9Pattern that matches too soon
expect ">"A one-character pattern, >. Patterns are unanchored and match anywhere in the output, so a banner or an earlier line that contains this character ends the wait early. Match more of the prompt, and anchor a regexp with $ (expect(1) encourages it when you can describe the end of the string).
- warningE4line 10Ends on a send
send "show running-config\r"The script's last act is a send. When the script ends, Expect closes the connections to its spawned processes (expect(1)), so whatever the program prints in answer is never read, and the program may not have finished. End with expect eof, an expect for the final prompt, or interact.
The explainer reads the script's text and never runs it. It follows the bodies of expect, if, foreach, while, for, switch, catch and proc in source order, so it cannot know which branch a run takes, how many times a loop runs or whether a procedure is ever called. Patterns and strings that depend on a variable are shown as written. Every fact about Expect comes from expect(1), cited under Sources.