Network Automation Basics
Automate Shell Scripts with Expect
I remember in my early days of network engineering when I had a checklist that required me to SSH and Telnet into several servers and check the status or configurations to make sure everything was running as it should. It was tedious and I had to do it multiple times a day.
Then I learned about a tool called Expect, which is a command/scripting language that talks with your interactive programs or scripts that require user interaction.
Basically, when the device you’re logging-into requires a password or other input, Expect will type it for you, saving you a lot of time and trouble. Let’s go over how this works, with an example.
1. Install Expect if you haven’t yet. From my Terminal I used ‘brew install expect’ but you might use apt-get, yum, etc., to install it.
2. Understand the basic Expect commands:
- spawn - starts a script or a program like the shell, FTP, Telnet, SSH, SCP, etc.
- expect – waits for input
- send - sends a reply to a script or a program.
- interact– allows you to jump in and interact with the shell during the automation
3. Use your favorite IDE to make an expect file. Make sure you name it with an ending of ‘.exp’ I named mine login.exp
4. Write the Expect script. For my example, I’m going to use my Expect script in my Terminal to SSH into a DevNet Sandbox IOS-XR rotuer, verify the running configuration and print the output to a log file.
#!/usr/bin/env expect
set timeout 60
log_file ios_xr.log
spawn ssh admin@sandbox-iosxr-1.cisco.com
expect "Password:" { send "C1sco12345\r" }
expect "#" { send "terminal length 0\r" }
expect "#" { send "conf t\r" }
expect "#" { send "show running-config\r" }
expect "#" { send "end\r" }
expect "#" { send "exit\r" }
Here’s a breakdown of what’s in the Expect script above:
- The first line, beginning with ‘#!’ lets the interpreter know this is an Expect file
- Then I set the timeout to 60 seconds because the default is 10 seconds for Expect. I don’t want it to drop the shell too quickly.
- After that, I use the ‘log_file’ command to set the name of the file to store the running configuration.
- Next, I use the ‘spawn’ command to SSH into the box
- Finally, I alternate with a series of ‘expect’ and ‘send’ command to interact with the device and ultimately log out.
- Of note is the ‘terminal length 0’ command. Without this, the running config would only be partially displayed and would require continuous ENTERs. On a related note, the ‘\r’ at the end of most lines serves the same purpose as one ENTER.
From the directory where my Expect script is located, I run the command ‘sudo ./login.exp’ and voila, I can see the commands executing in my Bash terminal and I have the configuration saved in my log file.
![ios_xr_log.png ios_xr_log.png](https://community.cisco.com/t5/image/serverpage/image-id/155343iC5858B52CAAA0A0C/image-size/large?v=v2&px=999)
We just turned a minutes-long mundane task into a few seconds of efficiency!
*If you run into an issue where you don’t have permission to execute your file, you can use the chmod +x commands to give you execution permission. This script will automate everything except for your sudo login, for security purposes.