Recently at work, we had to write a script to upload several files to an ftp server. Initially, we developed a first version using here documents. It was not bad, but it wasn’t exactly what we needed. We told ourselves: “We just want to do this as if we were typing it”. After googling for a couple of minutes, we found
expect is an utility to program a dialogue with interactive programs. How does this work? It is something like the following:
- I would launch this program
- I would expect something in the terms of this string as a result
- I would send this or that command
- I would expect this other string as a result.
For example, in order to upload a certain file to an FTP server, an operator would interact with the ftp client like this:
ftp ftp://$USER:$PASS@$FTP_HOST Connected to server.wonderland.com 220 Welcome to SERVER 331 Please specify the password. 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. 200 Switching to Binary mode.
Now, we would need to type:
ftp> put file1 local: file1 remote: fichero1 229 Entering Extended Passive Mode (|||30078|). 150 Ok to send data. 226 Transfer complete.
And now, to exit and finish the session, we would type again:
ftp> quit 221 Goodbye.
expect helps us to automate these kind of tasks. It works by telling it what you expect next to be printed on the screen and acts accordingly. This might seem a bit confusing. Let’s see an example:
Again, imagine we want to upload a file to an FTP server. We could write a small script like the following:
#!/usr/bin/expect -f set REMOTE_SERVER "ftp://user:pass@remote_host" # Connect to server spawn ftp $REMOTE_SERVER # Set binary mode and wait expect "ftp>" send "bin\r" expect "ftp>" send "put file1"
So basically, you have the
expect command that wait for certain output to happen and then use the
send command to type commands back to the program.
expect allows the use of regular expressions too so if you have some program that answers with codes like these:
OK - Transfer success OK - Name change success ....
you can write something like:
expect "OK - .*"
expect is a nice replacement for those boring, repetitive tasks. You can even use it to simulate an intelligent program by detecting patterns in the sentences of the user :)
The scripting language used by expect is TCL. It is not difficult to learn and if you just need to write small scripts, you can be ready in few minutes.