The Linux expect command lets you automate interactions with scripts and programs. You can send any kind of response to the script when it is waiting for some text input.
Automation Means Efficiency
When you administer a Linux computer or group of computers you’ll run up against many repetitive tasks. The obvious answer is to write a script to perform the bulk of the work for you. The Bash shell, like all modern shells, provides a rich and flexible scripting language.
Scripting a long-winded or tedious job gives you the flexibility to run that task when the office is closed, or in the quietest periods of a 24/7 operation. Scripts also give you repeatability. They won’t forget to perform a step, no matter how many times they are asked to perform the same chores.
That’s fine, as far as it goes. But if your script requires user interaction, or if it calls a program that will need human input, what can you do? You don’t want to have to be present when the script runs, or if you are present, to be watching the terminal window ready to jump in and hit a few keys.
Linux has the
yes command, which sends a stream of “y” characters or other user-specified string to the terminal window. If a program is waiting for a response to a yes or no question it’ll be force-fed one of the “y” characters. It’ll accept it as input and will be able to proceed. You need to pipe the output from
yes into the script.
yes | script.sh
You might not want to send a “yes.” Perhaps you need to respond with a “no.” You can do that too, using the
yes command. You can send any phrase you like, you’re not restricted to responses like “y”, “Y”, “Yes”, “n”, “N”, or “No.” Perhaps you need to send an “r” for reinstall to an ”
install/upgrade/reinstall [i/u/r] ” prompt.
yes command can’t cope if it needs to provide more than one different type of response. For that situation, we need to use
RELATED: How to Use the yes Command on Linux
Installing the expect Command
We tested expect on Ubuntu, Fedora, and Manjaro. The package wasn’t bundled with these distributions, so it had to be installed. On Ubuntu type:
sudo apt install expect
On Fedora, the command you need is:
sudo dnf install expect
On Manjaro we use
sudo pacman -Sy expect
How expect Works
expect command lets you manage the two ends of a conversation between your set of prepared answers and the program or script that you’ll be sending them to. You do this by creating an “expect” script that watches for prompts in the main script and sends the appropriate response for each one.
Let’s say you have a backup script that asks for a source directory name and a target directory name. it then makes a copy of the source directory in the target directory. Without the bits that do the file copying, your script might look something like this:
#!/bin/bash echo "Directory to backup?" read source_directory echo "Backup location?" read target_directory echo echo "Target directory:" $target_directory
All this script does is ask for the paths to the two directories. It prints the target directory to the terminal window so that we can see that it received a response from
expect and that it could read it correctly.
To provide the other half of the conversation we create an “expect script.” By convention, these have a “.exp” extension. This example will work with our “backup.sh” script.
#!/usr/bin/expect -f set timeout -1 spawn ./backup.sh expect "Directory to backup?r" send -- "/home/dave/Documents/r" expect "Backup location?r" send -- "/media/dave/external/backupr" expect eof
This shows the main three commands in expect scripts, the
The first thing to notice is the shebang is referring to
expect, not to Bash. The
-f (file) flag tells
expect the responses are coming from a file.
We effectively turn the timeouts off by setting them to infinity with -1.
spawn command launches the backup script.
We know the two questions the “backup.sh” script will ask us. For each question in turn we create an “expect” line. These contain the text prompt that will be sent to the terminal window by the “backup.sh” script. This what the
expect program will watch out for. When
expect sees the prompt, the text in the
send line is returned to the “backup.sh” script.
Make both scripts executable:
chmod +x backup.sh
chmod +x backup.exp
And use the “backup.exp” script to fire off the process.
You can see the two prompts from “backup.sh” and the responses from “backup.exp.”