expect command
Linux

Expect command and how to automate shell scripts like magic

In the previous post, we talked about writing practical shell scripts and we saw how it is easy to write a shell script. Today we are going to talk about a tool that does magic to our shell scripts, that tool is the Expect command or Expect scripting language.

Expect command or expect scripting language is a language that talks with your interactive programs or scripts that require user interaction.

Expect scripting language works by expecting input, then the Expect script will send the response without any user interaction.

You can say that this tool is your robot which will automate your scripts.

If Expect command if not installed on your system, you can install it using the following command:

$ apt-get install expect

Or on Red Hat based systems like CentOS:

$ yum install expect

 

Expect Command

Before we talk about expect command, we need to talk about the basic commands that Expect uses to interact with a program or script:

spawn                   Starting a process or a program.

expect                  Waiting for output from a process or a program.

send                      Sending a reply to a process or a program.

interact                Allowing you in interact with a process or a program.

 

  • The spawn command is used to start up a process or application, such as the shell, FTP, Telnet, ssh, scp, and so on.
  • The send command is used to send a reply to a process or a program. This works like echo in our shell scripts.
  • The Expect command is used to wait for some input.
  • The interact command allows you to define a predefined user interaction.

We are going to type a shell script that asks some questions and we will make an Expect script that will answer those questions.

First, the shell script will look like this:

Now we will write the Expect scripts that will answer this automatically:

The first line defines the expect command path which is  #!/usr/bin/expect .

On the second line of code, we disable timeout by setting the expect timeout variable to -1. Then start our script using spawn command.

We can use spawn to run any program we want or any other interactive script.

The remaining lines are the Expect script that interacts with our shell script.

The last expect statement tells Expect about the end of file is expected and the script ends.

Now Showtime, let’s run our answer bot and make sure you make it executable.

$ chmod +x ./answerbot

$./answerbot

expect command

Cool!! All questions are answered as we expect.

If you get errors about the location of Expect command you can get the location using the which command:

$ which expect

We did not interact with our script at all, the Expect program do the job for us.

The above method can be applied to any interactive script or program.Although the above Expect script is very easy to write, but maybe the Expect script little tricky for some people, well you have it.

Using autoexpect

To build an expect script automatically, you can the use autoexpect command.

autoexpect works the same way as the script works. We enter autoexpect on the command line, and a new session is started that saves all the keystrokes in a file until the application ends.

$ autoexpect ./questions

autoexpect command

A file is generated called script.exp contains the same code as we did above with some additions that we will leave it for now.

autoexpect script

If you run the auto generated file script.exp, you will see the same answers as expected:

autoexpect script execution

Awesome!! That super easy.

There are many commands that use timestamps in output or show transfer statistics or any changeable output, as in the case of FTP programs, the expect script may fail or stuck. If you get this type of output when using autoexpect, either delete the changeable data from the expect script or use wildcards to represent the data.

Working with Variables

The set command is used to define variables in Expect scripts like this:

set VAR1 5

To access the variable, add $ in front of the variable name like this $VAR1

To define command line arguments in Expect scripts, we use the following syntax:

set VAR [lindex $argv 0]

Here we define a variable VAR as a pointer to the first command line argument $argv 0 using set command.

For our shell script, we want to define the first argument as the name my_name. The second command line argument is assigned to the favorite, my_favorite. So the variables definition will look like this:

Let’s add variables to our script:

Now try to run the Expect script with some parameters to see the output:

$ ./answerbot SomeName Programming

expect command variables

Awesome!! Now our automated Expect script is more dynamic.

Conditional Tests

You can write conditional tests using braces like this:

We are going to change our script to return different conditions, and we will change our Expect script to handle those conditions.

We are going to emulate different expects with the following script:

A random number is generated ever time you run the script and based on that number, we put a condition to return different expects.

Let’s make out Expect script that will deal with that.

expect command conditions

Very clear. If the script hits the topic output, the Expect script will send programming and if the script hits movie output the expect script will send star wars. Isn’t cool?

If else Conditions

Expect also provides if else and other basic control structures, you can write it like this:

expect command if command

Note: The opening brace must be on the same line.

While Loops

Expect uses similar syntax for a while loop as our shell scripts use. But again, you must use braces to contain the expression like this:

expect command while loop

For Loops

To make a for loop in expect, three fields must be specified, like the following format:

expect command for loop

User-defined Functions

Expect supports functions using the proc Expect operator. You can define a function like this:

And you can use them after that.

expect command user-defined functions

Interact Command

Sometimes your Expect script contains some sensitive information that you don’t want to share with other users who use your Expect scripts, like passwords or any other data, so you want your script to take this password from you and continuing automation normally.

The interact command reverts the control back to the keyboard.

When this command is executed, Expect will start reading from the keyboard.

This shell script will ask about the password as shown:

Now we will write the Expect script that will prompt for the password:

interact command

After you type your password type ++ and the control will return back from the keyboard to the script.

Expect language is ported to many languages like C#, Java, Perl, Python, Ruby and Shell with almost the same concepts and syntax due to its simplicity and importance.

Expect scripting language is used in quality assurance, network measurements such as echo response time, automate file transfers, updates, and many other uses.

I hope you now supercharged with some of the most important aspects of Expect command, autoexpect command and how to use it to automate your tasks in a smarter way.

Thank you.