How to automate interactive cli commands with expect

Expect is a free and open source utility we can use to automatically answer to interactive prompts according to scripts which includes expects/sends commands. In this tutorial, we learn how to install expect on the most used Linux distributions, how to use it to automatically answer to interactive prompts, and how to generate expect scripts with autoexpect.

In this tutorial you will learn:

  • How to install expect on the most used Linux distribution
  • How to write an expect script
  • How to use autoexpect to automatically generate expect scripts
How to automate interactive CLI commands with expect on Linux
How to automate interactive CLI commands with expect on Linux
Category Requirements, Conventions or Software Version Used
System Distribution-agnostic
Software expect
Other Software installation requires root privileges
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Installing expect

Although expect is available in the repositories of all the major Linux distributions, it is usually not installed by default. To install the utility on Fedora and other distributions of the Red Hat family, such as Rocky Linux, we can use the dnf package manager:

$ sudo dnf install expect

To install the package on Debian or other distributions based on it, instead, we can run:

$ sudo apt-get update && sudo apt-get install expect

Expect is also available in the Archlinux “Extra” repository. We can install using pacman:

$ sudo pacman -Sy expect

Expect usage example

Certain command line utilities and programs, beside being able to work interactively, allow the user to pass required arguments via dedicated options. In other cases, for a variety of reasons, they lack those options: that is where expect comes in handy.



By creating dedicated expect scripts, we can automate the execution of commands which require user interaction, providing predefined answers to expected prompts. Let’s see some basic examples. Here we create a script which asks some question (name, country, and email address):

#!/bin/bash 
read -p "What is your name? " name 
read -p "What is your country? " country 
read -p "Enter your email address: " email

The script is trivial, doesn’t perform any data validation, but it is enough for our purpose. We save it as “prompts.sh”, and give it executable permissions:

$ chmod +x prompts.sh

Once we execute it, as expected, it prompts us to provide the requested information:

$ ./prompts.sh
What is your name? Egidio
What is your country? Italy
Enter your email address: nomail@gmail.com

Once we answer the first prompt created by the script, and press “Enter”, the second is displayed, and so on. Since we know how prompts look like, we can create an expect script which automatically answer them for us, without any interaction. Here it is:

#!/bin/expect 
spawn ./prompts.sh 
expect "What is your name?" { send "Egidio\n" }
expect "What is your country?" { send "Italy\n" }
expect "Enter your email address" { send "nomail@gmail.com\n" }
expect EOF

The first thing you should notice, is that we used /bin/expect as the script interpreter, instead of /bin/bash: this is to avoid being forced to pass the script as argument to the expect program (do not confuse it with the name of the command we can use in the script), each time we want to invoke it. In our trivial script, we used three commands: spawn, expect and send.

The first one, spawn, runs a new process, and connects the standard output, standard input and standard error file descriptors of the latter, to expect, so that it can parse the program messages and perform the scripted actions.



The expect command waits until a certain pattern matches the output of the executable launched with the spawn command. In the example above, the match can happen anywhere in the output. If the output of the command was: “Tell me, what is your country?”, the pattern would have matched nonetheless. To enforce a most strict match, we could have used regular expression anchors: ^ and $. They match, respectively, the beginning and the end of the data stream.

If the pattern doesn’t match the output, and the timeout expires, the expect command returns, and the execution of the script continues to the next instruction. The default timeout is 10 seconds; we can change it by assigning a different value to the “timeout” variable:

set timeout 20

In the example above, we set a timeout of 20 seconds; using a value of -1 disables the timeout altogether, so that expect waits indefinitely, while a value of 0 causes the opposite behavior: expect doesn’t wait at all.

The last command we used is send. The send command sends a string to the process. Notice that we included the \n character (end of line) in the string we provided, since no formatting is applied by default.

In the last line of the script, instead of a specific message, we matched for EOF (End Of File). We save the script as prompts.exp (the “.exp” extension is just a convention) and make it executable. Finally, we launch it. Here is its output:

$ ./script.exp 
spawn ./prompts.sh
What is your name? Egidio
What is your country? Italy
Enter your email address: nomail@gmail.com

Autogenerate expect scripts with autoexpect

Autoexpect is a utility which comes together with expect: we can use it to generate expect scripts as results of interactive session. Instead of writing an expect script by hand, we can use autoexpect to run the command which requires user interaction, e.g:

$ autoexpect ./prompts.sh



The script we provide as argument to autoexpect runs; it requires our interaction, as it would normally do. Once the script exits, however, an expect script is generated: script.exp. When executed, it will replicate the actions we performed interactively.

Closing thoughts

In this tutorial, we learned the basics of how to use expect to automate interactive commands. We saw a very basic example of how to write an expect script, using the spawn, expect and send commands. Finally, we saw how it is possible to automatically generate an expect script using the autoexpect utility. Here we barely scratched the surface of what we can achieve using expect scripts. Please take a look at expect manual for a more in-depth knowledge.



Comments and Discussions
Linux Forum