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 for input.

Expect scripting language works by expecting input, and upon receiving the expected input, the Expect script will send a response without any user interaction, just like magic.

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                   Starts a process or a program.

send                      Sends a reply to a process or a program.

expect                  Waits for output from a process or a program.

interact                Allows 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. You must specify the proper cursor control when talking with an interactive application, using \r for carriage return and \n for each new line. Carriage returns and line feeds are not automatically implied.
  • The Expect command is used to wait for specific output from a process or a program, just as read command that waits for input in a shell script
  • The interact command, which enables us to program a predefined user interaction in our Expect scripts. For example, we might want to have an Expect script that will log us into an FTP site and then turn control over to the end user.

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 executing shell, but in this case #!/usr/bin/expect we specify the path to the Expect command because those lines will be interpreted by the Expect command.

On the second line of code, we disable timeout by setting the expect timeout variable to -1. Next, we start our interactive script.

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 Automatically Create an Expect Script

To create an expect script quickly and 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 result:

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. For example, to assign the value 5 to the variable VAR1, we use the following syntax:

set VAR1 5

To access the variable, we use the same technique as we do in a normal shell script —add a $ in front of the variable name $VAR1

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

set VAR [lindex $argv 0]

The set command defines the variable VAR as a pointer to the first command line argument $argv 0.

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 modify our script with the new variables:

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

Expect handle conditional test by 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

The for loop in Expect works differently from the for loop in a shell script.

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 uses your Expect scripts, like passwords or any other data, so you want your script to take this password from you and continuing automation normally.

Expect provides a command that turns control from the spawned script or program to you, this command is interact command.

When this command is executed, Expect script stops reading commands from the script and instead begins 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.