How to Automate Responses Using Expect and Autoexpect in Linux

The automate command in linux takes a scripts that prompts for input and automates running and responding to those input.
It basically talks with your interactive programs or scripts that require user interaction.

When a program asks for user input, expect send the response without any user interaction.

Checkout:

Installation

Debian apt based systems like Ubuntu

sudo apt update
sudo apt install -y expect

Red Hat based systems like Centos

# Centos 7
sudo yum install -y expect

# RHEL 8 and 9 based distros
sudo dnf install -y expect

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

which expect
which autoexpect

Example

Save this in name.sh

#!/bin/bash

echo "What is your name?"
read name

echo "Your name is ${name}"

Make the script executable:

chmod +x name.sh

# Execute
./name.sh

When I run the script manually it prompts me to enter name with What is your name? then prints out after i enter.

We can use expect to provide an automated response to the query. Here is the script:

Save this to auto.exp

#!/usr/bin/expect

set timeout -1
spawn ./name.sh
expect "What is your name?\r"
send -- "John\r"
expect eof

Make readable and executable:

chmod +x auto.exp

This is the output when the script is executed with ./auto.exp:

➜ ./auto.exp
spawn ./name.sh
What is your name?
John
Your name is John

Working with Variables

You can use the set command to define variables in expect scripts like this:

set user kip
set age 10

To access the variable, precede it with $ like in bash (e.g. $user)

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

set USER [lindex $argv 0]

Here we define a variable USER, which equals the first passed argument.

You can get the first and the second arguments and store them in variables like this:

set USER [lindex $argv 0]
set PASSWORD [lindex $argv 1]

Example of script with variables

Another way to go about it without creating a script:
Example to change sftp password. Save these to ./sftp_password_change.exp.

#!/usr/bin/expect

set timeout 10
set curpass [lindex $argv 0];
set newpass [lindex $argv 1];
set user    [lindex $argv 2];
set server  [lindex $argv 3];

expect <<EOF
    spawn sftp -P 15422 $user@$server
    expect "Password:"
    send "$curpass\r"
    expect "Old Password:"
    send "$curpass\r"
    expect "New Password:"
    send "$newpass\r"
    expect "Reenter New Password:"
    send "$newpass\r"
    expect "sftp>"
    send "exit\n"

Run the sctipt with

./sftp_password_change.exp $curpass $newpass $user $server

Autoexpect

autoexpect command allows you provide your script as an argument then it will create the script for you.
You use a command like autoexpect ./installapp and it will build an expect script with the answers that you provide:

$ autoexpect ./name.sh
autoexpect started, file is script.exp
What is your name?
John
Your name is John
autoexpect done, file is script.exp

The resultant script.exp file will then include an explanation that it was created with autoexpect and will include the responses you provided.

The autoexpect tool prepares the script for non-interactively running an installation. You can then do installs without having to supply the details or just schedule them to run on their own.

This is the generated content without comments

$ cat script.exp
#!/usr/bin/expect -f
#
set force_conservative 0  ;# set to 1 to force conservative mode even if
              ;# script wasn't run conservatively originally
if {$force_conservative} {
    set send_slow {1 .1}
    proc send {ignore arg} {
        sleep .1
        exp_send -s -- $arg
    }
}

set timeout -1
spawn ./name.sh
match_max 100000
expect -exact "What is your name?\r
"
send -- "John\r"
expect eof

Conclusion

The expect command is handy for running scripts that require a long series of answers and allows you to run them in an un-manned fashion while autoexpect makes it easy to create expect scripts without stressing out over the syntactical details.

comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy