Expect comes with a bunch of examples that are indispensable and unique full-function tools in their own right like cryptdir, passmass, unbuffer, kibitz, dislocate, etc, etc.
The latest cool new Expect whizbang: multixterm.
LV offers an example of his use of Expect: "Our local public library used to have a telnet interface to its patron account system. I wrote an Expect script which logged onto the system, queried for the holdings status of each account in my family, then logged off. I would run this from cron and get a report as to which books were coming up for return, what items were held for pick up, and so on. I then placed the text version of that report into a directory where a daily sync to my Palm Pilot would result in a PalmOS memo containing this info."
This is how you send ctrl+C through expect: send \003
The Let's Grab Everything Example by Froggy
Oftentimes I just want to grab all output and do as I wish with it afterwards. This example will demonstrate how to grab everything from a shell command. In this example, I launch the bash shell with the spawn command, then I send commands to the bash shell with exp_send, and finally I use expect to get retrieve my results.
# load the Expect package into Tcl package require Expect spawn bash exp_send "ls -l\n" set accum {} expect { -regexp {..*} { set accum "${accum}$expect_out(0,string)" exp_continue } } puts $accum
proc kermconnect {} { global opts expect_out spawn_id telnetbase if {$opts(host) ne ""} { spawn kermit -Y -j $opts(host) [expr $telnetbase + $opts(port)] } else { # use default kermit settings spawn kermit } set try 0 expect { "C-Kermit>" { send c\r } timeout { if {$try == 0} { send "set prompt\r" incr try exp_continue } failed "finding C-Kermit prompt" } } } proc kermdisconnect {} { global expect_out spawn_id expect "Kermit>" { send "close\r"} expect { timeout {failed "close connection"} -re "Closing connection.*Kermit>" { send q\r; after 100 } } uplevel #0 catch {close} uplevel #0 catch {wait} }
RJ Here's a simpler way to catch all of the output:
proc exec_it {command} { spawn -noecho $command log_user 0 expect eof return [string trimleft $expect_out(buffer) $command] }
COSI-NMS [L1 ] is a SourceForge-hosted project to which Cisco contributes. Several of the Cisco-specific examples which appear there are Expect scripts.
LV Here's a question from an expect developer:
#!/usr/bin/expect -- set timeout 30 spawn /usr/local/bin/scp -P 36000 user@ip:/data/myfile /data1 expect { "password:" { send "password\r" } "yes/no)?" { send "yes\r" set timeout -1 } timeout { exit } eof { exit } }
when scp executes normally, everything is ok. But when the host does not exist, or is not reachable, the script stops, waiting for the "password" prompt. Because the file to be copied is very large, the code needs to cancel the timeout. How would one get the result of scp so as to handle this properly? RJ Larry, made some changes to above - see if that does what you need. Also, if you only get the end of the file, try expanding the buffer with the match_max command right after the spawn.
dcd Probably not related directly to expect, but that's where I encountered it, the following exec failed:
exec cat myfile | nc -w 5 $opts(host) [expr $tcpipbase + $opts(port)]
with a broken pipe error when run from a script, but worked when entered interactively in expect. After many hours of hair-pulling, this fixed it:
exec cat myfile | /usr/bin/nc -w 5 $opts(host) [expr $tcpipbase + $opts(port)]
Note that kermit will emulate telnet, but when you need a raw tcpip connection, nc will do the job..