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.