You can write Expect programs that automate live sessions, handling any tasks where a user interacts with the system. This suggests a multitude of uses, but where it has been most popularly applied is in software testing and in automating network transfers, such as site updates or downloads.
Expect is a product of the US government, having been created by Don Libes, a computer scientist at the National Institute of Standards and Technology (NIST). It has been around for years, and while its functionality has stayed the same, the reason for using it keeps changing.
"Expect has always been a 'hole-plugger' in the sense that it only has value until existing holes in other tools are plugged," Libes says. Many of the holes it plugged in the past -- like scripting outbound email messages -- have been filled by new or improved tools. But there's still no shortage of holes that Expect can handle.
"After all, tools like telnet and ssh still offer very limited control, so Expect is useful there," Libes says. "Expect will also remain useful when dealing with custom software and hardware, where no one has time to embed any kind of control language, or proprietary stuff where there's no way to do it if the vendor hasn't provided a similar mechanism, or the fusion of tools which were never designed to work together."
Basic commands
The first thing everybody seems to try when learning Expect must be how to use it to script a call to the passwd command. The autopasswd program is one of the examples that Expect comes with. When you run it (as root) with the arguments of a username and password, it calls the passwd command and resets the given user's password. Very simple -- but also quite useful, because you can't use normal shell redirection to do it. Now imagine this tiny automation repeated 1,000 times for a batch of users, and you start to see how handy Expect can be. Whenever you have to type something over and over again, Expect can completely automate the interaction. And with the Tk toolkit, it's a trivial matter to build graphical X11 dialogs around your Expect programs.
The meat of the autopasswd program is just this:
set password [lindex $argv 1] spawn passwd [lindex $argv 0] expect "password:" send "$password\r" expect "password:" send "$password\r" expect eof
You can probably guess the meaning of the commands -- first, the password variable is defined as the second command-line argument; then spawn starts a new process, running the arguments given to it -- in this case the passwd command. Then the expect command waits for the text "password:" -- and when it comes, the send command sends the new password to the process.
This example neatly encapsulates the whole raison d'etre of Expect, and contains almost all of its important commands. In addition to these, the other core command is interact, which passes control of the process back to the user, who can interact with it directly via standard input as normal. Control can be passed back to the Expect program in various ways, including by what the user types or by what is output by the process.
Get the weather
One of the more famous and easily demonstrable Expect applications is weather, another example script that comes with the standard distribution. It uses the Weather Underground's excellent telnet interface to its weather server to get an up-to-the-minute bulletin from the National Weather Service.
Run weather with the three-letter city code you'd like to get a report on (a lot of Linux systems have a list installed at /usr/share/doc/miscfiles/airport.gz). You'll see Expect opening the telnet connection and choosing the city weather report from a menu (if you want to get fancy, all this cruft can be wiped out with the user_out command), and then the actual weather bulletin is output:
$ weather nyc ... connection messages ... Weather Conditions at 11:51 AM EDT on 27 Jul 2006 for New York JFK, NY. Temp(F) Humidity(%) Wind(mph) Pressure(in) Weather ======================================================================== 81 74% SSW at 10 30.00 haze Forecast for New York, NY 1013 am EDT Thu Jul 27 2006 .This afternoon...Partly sunny with a slight chance of showers and thunderstorms. Humid with highs in the upper 80s...cooler near the ocean. South winds 10 to 15 mph. Chance of rain 20 percent. .Tonight...Partly cloudy. A chance of showers and thunderstorms mainly after midnight. Patchy fog after midnight. Humid with lows in the mid 70s. Southwest winds 10 to 15 mph. Chance of rain 30 percent. ... more ... $
Examples galore
The Expect distribution comes with about 50 example scripts in all. In addition, the Expect distribution site at NIST has a directory of scripts contributed by users that are fun to browse through.
These examples run the gamut from the silly -- a real-time simulation of someone typing out the "99 Bottles of Beer On The Wall" song -- to the seriously useful. There's multixterm , for instance, which lets you open multiple xterms and send the keystrokes from your input window to all of them simultaneously. And xkibitz lets two (or more) users share the same shell or other program from their terminals -- an excellent hands-on training tool.
These programs are always informative -- even the beer song demonstrates how pseudo-random input can be generated and passed in real-time to a process, perhaps for testing purposes -- and they're worth studying to give you ideas of the diverse ways that Expect can be used.
Note: Comments are owned by the poster. We are not responsible for their content.
It's nice to launch VNC with the necessary password included on the command line. It's also nice to automate rsync without creating keys beforehand.
Just be aware that of course it's not super-safe to let plaintext passwords in your<nobr> <wbr></nobr>.yourshell_history.<nobr> <wbr></nobr>;)
My 2 eurocents contributions (wich can surely be improved)<nobr> <wbr></nobr>:
autovncviewer
autorsync<tt>#!/bin/bash
# Syntax : autovncviewer host password vncoption1 vncoption2<nobr> <wbr></nobr>...
# Example : autovncviewer mypc "weakpwd" -bgr233
host="$1"
password="$2"
shift
shift
[ -z "$TMP" ] && TMP=/tmp
cat > $TMP/autovncviewer.expect.tmp.$$ << EOF
#!/usr/bin/expect -f
set host [lindex \$argv 0]
set password [lindex \$argv 1]
set timeout -1
spawn vncviewer \$host $*
expect "assword:"
send "\$password\r"
expect eof
EOF
chmod 700 $TMP/autovncviewer.expect.tmp.$$
$TMP/autovncvie<nobr>w<wbr></nobr> er.expect.tmp.$$ "$host" "$password"
rm $TMP/autovncviewer.expect.tmp.$$</tt>
<tt>#!/bin/bash
# Syntax : autorsync password rsyncoption1 rsyncoption2<nobr> <wbr></nobr>...
# Example : autorsync passwd -Pavz joe@machine1:/home/joe/data<nobr> <wbr></nobr>.
password="$1"
shift
[ -z "$TMP" ] && TMP=/tmp
cat > $TMP/autorsync.expect.tmp.$$ << EOF
#!/usr/bin/expect -f
set password [lindex \$argv 0]
set timeout -1
spawn rsync $*
expect {
"(yes/no)" {
send "yes\r"
expect "assword:"
send "\$password\r"
}
"assword:" { send "\$password\r" }
}
expect eof
EOF
chmod 700 $TMP/autorsync.expect.tmp.$$
$TMP/autorsync.expe<nobr>c<wbr></nobr> t.tmp.$$ "$password"
echo $?
rm $TMP/autorsync.expect.tmp.$$</tt>
I'll be the third one to ask you: Do you have any idea what you're talking about?
Have you ever even tried to use expect to see what it is capable of? Or have you just dismissed it completely because "it's bundled with tcl" (I have no idea what that's supposed to mean)?
If you'd just take a few minutes to familiarize yourself with expect, you'd understand that to have any useful functionality beyond '<tt>expect $this</tt>' and '<tt>send $that</tt>', you need a pretty much full-featured programming language. And for that you need an interpreter, which by the way is a very complex piece of software to design and implement from scratch.
To me it seems very UNIX-like that Don Libes used an existing interpreter for expect instead of creating yet another half-arsed scripting language to haunt mankind.
Btw, if you're just making excuses because you're too lazy to learn tcl, go ahead and use <a href="http://sourceforge.net/projects/expectpy/" title="sourceforge.net">expectpy</a sourceforge.net>
or <a href="http://sourceforge.net/projects/expectperl/" title="sourceforge.net">expect.pm</a sourceforge.net>
. Same functionality, different kind of bloat. Would these be "more standalone" for you?
This is just a short example of what Expect can do, it isn't a bullet proof password change utility, but hopefully shows you a bit better what expect can do. First it does regular expressions, because not all passwd programs are the same, some use upper case some use lower case, and here I am expecting both. The 'exp_continue statement tells expect to continue evaluating output, where it picks up the 'Re-enter' statement.<tt>set password [lindex $argv 1]
spawn passwd [lindex $argv 0]
expect {
-re "\[N|n]ew \[P|p]assword:" {
send "$password\r"
exp_continue
}
-re "[R|r]e-enter new \[P|p]assword\r"
send "$password\r"
exp_continue
}
"passwd: Password too short - must be at least 6 characters." {
puts stdout "Bad Password"
exit 1
}
eof {
exit
}
}</tt>
PExpect in Python
Posted by: Anonymous Coward on August 04, 2006 12:16 AMUnless, of course, you like programming in TCL.
#