dcsimg

Are You Expecting? Your Boss Should Know

The quest to save labor makes us do some crazy things but when you're expecting, there is an easier way.

If there’s a push for labor-saving ideas at your workplace, here’s one for you: Expect. Expect is a simple scripting language that allows you to initiate interactive command line sessions in an automated fashion. For example, if you want to setup a script to login to a remote system, gather some files and then disconnect from the remote system; expect is the tool to use for that interactive session. But what’s better than creating a script to automate some repetitive task? Automating the creation of that script, of course. And, you can do just that with Autoexpect.

Creating an Expect script can prove tedious, especially for those of us who have attention deficit disorders. It’s hard to focus on each detail of a stepwise procedure to perform a simple but repititious task. That’s where Autoexpect saves the day. Autoexpect “watches” your keystrokes and writes them to an Expect script that you can then execute to perform the recorded task.

Autoexpect isn’t perfect but it beats taking the painfully manual approach to creating Expect scripts.

The Basics

To use Expect or Autoexpect, you will need Tcl, Tk and Expect source code unless your distibution has autoexpect packaged with Expect. Installation by either method is easy to accomplish but your particular distribution might not include Autoexpect as part of the binary packages.

Grab the sources for Tcl and Tk from the Tcl Developer Exchange and the Expect sources from Sourceforge.net Expect site. Compile Tcl first, then Tk and finally Expect. There’s nothing tricky about these packages. Unzip them and compile and install each with a simple: ./configure ; make ; make install.

Once you have all three installed, it’s time to try out some simple Expect scripts.

Lowered Expectations

Expect, as explained earlier, automates repetitive keyboard interactive tasks. To “teach” the script how to respond to prompts, you must know what the prompts are. The only way to do that is to step through a session yourself and record the prompts and responses as you go. After going through this exercise, you’ll understand why you’d want to use Autoexpect. In this example, you’re going to create an expect script to connect to another system, login, run a ps command and then logout.

To begin, open your favorite text editor (vi, of course) and enter some commands.


#!/usr/local/bin/expect -f

spawn ssh slartibartfast
expect "password: "
send "beeblebrox\\r"
expect "$ "
send "ps -ef\\r"
send "exit\\r"
expect eof

Save the file with any name you want and then make it executable. Now, an explanation of the Expect script you created. The spawn command launches an executable file for you. In this example, the command is ssh with host (slartibartfast). The “expect” line is the last part of the prompt that the interactive script should expect to “see” for this interactive session. In other words, the script receives a prompt for the password. On the next line, you “send” the password prompt your password and a return (\r). The next item that the script should expect to see is the “$” prompt. Now, you send it a command: ps -ef\r. Finally, send the remote system the exit command to end the session.

Do you see how Expect works? You send a response to a prompt and then tell the script what to expect from the system. And, it goes back and forth like that for an entire session. You can also see how monotonous writing a very long or complicated script could become.

Great Expectations

Now that you’ve seen it done the hard way, have a look at Expect the way you’d have expected it to work. To use Autoexpect, simply type autoexpect at the command prompt. You’re returned to an interactive shell while Autoexpect records your keystrokes, mistakes and all, into a file named, script.exp. In this example, you’ll step through the same procedure but this time, you’ll perform the keystrokes as if Autoexpect isn’t watching you.

$ autoexpect
autoexpect started, file is script.exp
$ ssh slartibartfast
beeblebrox (Typed in but not shown on screen)
ps -ef
exit
Connection to slartibartfast closed.
$ Ctrl-D
autoexpect done, file is script.exp
$

Before you execute the script, you’d better take a look at it. Remember that Autoexpect isn’t perfect. Rarely do you create a script that doesn’t need editing. If you make any typos along the way, you’ll have to clean them out or each time you run your script, the typos will repeat along with your other commands.

When you open your script.exp file, you’ll notice a lot of text in it from the author, Don Libes of the National Institute of Standards and Technology. Scroll down to where your script begins with set timeout -1 Here is the script as Autoexpect created it (shortened due to the ps command output).

set timeout -1
spawn $env(SHELL)
match_max 100000
expect -exact "khess@debian5-1:~\\$ "
send -- "ssh slartibartfast\\r"
expect -exact "ssh slartibartfast\\r
khess@slartibartfast's password: "
send -- "beeblebrox\\r"
expect -exact "\\r
Last login: Wed Jul 21 11:23:28 2010 from 192.168.1.77\\r\\r
\\[khess@localhost ~\\]\\$ "
send -- "ps -ef\\r"
expect -exact "ps -ef\\r
UID        PID  PPID  C STIME TTY          TIME CMD\\r
root         1     0  0 09:37 ?        00:00:04 init \\[5\\]
 \\r
root         2     1  0 09:37 ?        00:00:00 \\[migration/0\]\\r
root         3     1  0 09:37 ?        00:00:00 \\[ksoftirqd/0\]\\r
root         4     1  0 09:37 ?        00:00:00 \\[watchdog/0\]\\r
root         5     1  0 09:37 ?        00:00:00 \\[events/0\]\\r
...
\\[khess@slartibartfast ~\\]\\$ "
send -- "exit\\r"
expect -exact "exit\\r
logout\\r
[H[JConnection to slartibartfast closed.\\r\\r
khess@debian5-1:~\\$ "
send -- ""
expect eof

The set timeout -1 disables timeouts for the script. The next line spawns a shell in which to operate, which is an unnecessary step as you can see from your manually created script. The match_max 100000 line raises the buffer to 100000 bytes from the default 2000. The expect -exact “khess@debian5-1:~\$ “ prompt is another unnecessary bit a la Autoexpect. The first line that corresponds to your manually created one is send — “ssh slartibartfast\r”. You should delete all lines that include expect -exact from your script as well as any echoed responses such as command results like those shown from the ps command.

Shown below is the final “cleaned” script.

#!/usr/local/bin/expect -f

set timeout -1
match_max 100000
spawn -- "ssh slartibartfast\\r"
expect "password: "
send -- "beeblebrox\\r"
expect "$ "
send -- "ps -ef\\r"
send -- "exit\\r"
expect eof

As you can see, this Autoexpect script looks very similar to your manually created one after cleanup. There are cases where you would want to keep the -exact response but if that response has anything to do with time, command output or anything that changes, you probably don’t want to use it.

The Unexpected

You’ll have to experiment with your scripts and adjust the timeout values, buffer sizes and prompts to ensure that you receive the desired results from them. Like any script, you’ll spend a little time debugging it.

The Autoexpect man page has a few helpful items in it but for real help, look to the Expect man page.

Remember that you’re really using Expect behind the scenes. Autoexpect is a script that assists you in making your Expect scripts a little less manual to create but don’t expect too much from it. Now, you can tell your boss that your’re expecting. In fact, tell him that you’re autoexpecting–all in the name of automation and to save those labor pains.

Next month, you can expect summer to really heat up with more system administration tips on redirected output and a little Bash magic from the trenches. See you there.

Fatal error: Call to undefined function aa_author_bios() in /opt/apache/dms/b2b/linux-mag.com/site/www/htdocs/wp-content/themes/linuxmag/single.php on line 62