6 Expect Script Examples to Expect the Unexpected (With Hello World)

by Balakrishnan Mariyappan on October 12, 2010

Expect scripting language is used to feed input automatically to an interactive program. It is easy to learn compared to other scripting languages. Using expect script sysadmins and developers can automate redundant tasks easily. It works by expecting specific strings, and sending or responding strings accordingly.

Following three expect commands are used when automating any interactive processes.

  • send – to send the strings to the process
  • expect – wait for the specific string from the process
  • spawn – to start the command

Make sure to install expect packages on your system, as it does not get installed by default. Once installed, you’ll see the expect interpreter as “/usr/bin/expect”. Generally, expect script files has .exp as extensions.

1. Expect “Hello World” Example

The following expect script is expecting the specific string “hello”. When it finds it (after user enters it), “world” string will be send as response.

#!/usr/bin/expect
expect "hello"
send "world"

2. Timeout On Expect String

By default, the expect timeout is 10 seconds. If you don’t enter anything for the expect command, it times out in 20 seconds. You can also change the timeout as shown below.

#!/usr/bin/expect
set timeout 10
expect "hello"
send "world"

3. Automate User Processes With Expect

With the help of expect, you can automate the user processes and get the expected output. For example, you might use this to simplify the project testing process by writing scripts for the test cases.

The below example does the addition program automation.

#!/usr/bin/expect

set timeout 20

spawn "./addition.pl"

expect "Enter the number1 :" { send "12\r" }
expect "Enter the number2 :" { send "23\r" }

interact

Execute this as shown below.

$ ./user_proc.exp
spawn ./addition.pl
Enter the number1 : 12
Enter the number2 : 23
Result : 35

In case, if you have written the code without interact command, then the script would exit immediately after sending the string “23\r”. Interact command does the control, hands over the job to the addition process, and produces the expected result.

4. Match and No Match Contents in $expect_out Variables

On the successful matching of string expect returns, but before that it stores the matched string in $expect_out(0,string). The string that are received prior plus the matched string are stored in $expect_out(buffer). The below example shows you the value of these two variable on match.

#!/usr/bin/expect

set timeout 20

spawn "./hello.pl"

expect "hello"
send "no match : <$expect_out(buffer)> \n"
send "match :  <$expect_out(0,string)>\n"

interact

The hello.pl program just prints only two lines as shown below.

#!/usr/bin/perl

print "Perl program\n";
print "hello world\n";

Execute it as shown below.

$ ./match.exp
spawn ./hello.pl
Perl program
hello world
no match :  <Perl program

hello>
match :  <hello>

5. Automate SU login into Other User Accounts

Expect allows you to pass the password for the Linux login account from the program, instead of entering the password on the terminal. In the below program, su login is automated to login into desired accounts.

#!/usr/bin/expect

set timeout 20

set user [lindex $argv 0]

set password [lindex $argv 1]

spawn su $user

expect "Password:"

send "$password\r";

interact

Execute the above expect program as shown below.

bala@localhost $ ./su.exp guest guest
spawn su guest
Password:
guest@localhost $

After running the above script, it logged into the guest user account from bala user account.

6. SSH Login into Another Machine

The example expect program shown below automates the ssh login from one machine to another machine.

#!/usr/bin/expect

set timeout 20

set ip [lindex $argv 0]

set user [lindex $argv 1]

set password [lindex $argv 2]

spawn ssh "$user\@$ip"

expect "Password:"

send "$password\r";

interact

Execute the above expect program as shown below.

guest@host1 $ ./ssh.exp 192.168.1.2 root password
spawn ssh root@192.168.1.2
Password:
Last login: Sat Oct  9 04:11:35 2010 from host1.geetkstuff.com
root@host2 #

Linux Sysadmin Course Linux provides several powerful administrative tools and utilities which will help you to manage your systems effectively. If you don’t know what these tools are and how to use them, you could be spending lot of time trying to perform even the basic administrative tasks. The focus of this course is to help you understand system administration tools, which will help you to become an effective Linux system administrator.
Get the Linux Sysadmin Course Now!

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

{ 23 comments… read them below or add one }

1 Juan October 12, 2010 at 4:59 am

You could also add one previous step to the SSH login for automated scripts: Test if remote key is already imported:

set timeout 5
expect “yes/no)?”
send “yes\r”

regards!

2 Greg Giese October 12, 2010 at 7:02 am

Sure wish I could still print these. Some good stuff that I often don’t have time to play with until later and then for get. When I printed them I could catch up on train or at home.

Thanks tho! Keep up the good work.

G

3 Scott Rowley October 12, 2010 at 7:33 am

Something to keep in mind with these expect scripts using passwords is that anything typed on the command line goes into your history. So you could end up saving your password into your history file. Then others with root access can see these passwords. Hopefully if they have root access though they should be someone thats trusted. Still I don’t want ANYONE knowing my passwords ;)

4 Brian Kastor October 14, 2010 at 7:48 am

@Scott, good point.. but there is a way around the History file. I don’t remember which option it is, but one of the HIST options will let you specify a space (literally hitting the space bar once) before the command and it won’t put it in the History file. I did this at a company where they had an appliance and refused to have the three of us all use the root account. So I got tired of them watching what I was doing.. I need to go back and look that one up.

5 Scott Rowley October 14, 2010 at 1:14 pm

@Brian, Interestingly enough I went to research this space method you mentioned and lo and behold, I was google routed right back to this website :)

http://www.thegeekstuff.com/2008/08/15-examples-to-master-linux-command-line-history/
Item #10

6 Pankaj December 21, 2010 at 7:47 am

@Brian/@Scott

The HIST options is: “unset HISTFILE”
We can set it as an alias in .bashrc file

alias xx=’unset HISTFILE’

7 james December 21, 2010 at 9:25 am

hello sir,

how can i install the expect packages? where i can get it?

8 fwonce January 18, 2011 at 1:36 pm

The match.exp example didn’t work out on my computer.

The output is:
spawn ./hello.pl
Perl program
hello world

I guess it’s because the hello.pl is over too soon to give match.exp enough time to send…
After add a line of “;” to the hello.pl I can see the output exactly the same as yours.

9 fwonce January 18, 2011 at 1:38 pm

the line added is <> sign…. it’s omitted….

10 Prakash April 25, 2011 at 3:59 am

How to send an exact string onto remote machine which contains metacharacters like $ where it is not set in the local script?

send “RELEASE=ls -l|grep -i $RELEASE_DATE”

Where in $RELEASE_DATE is not set in the script

11 Thierry August 12, 2011 at 2:39 am

For those who have trouble with the match.exp exemple like I did. Replace send “no match : \n” by puts stderr “no match : \n”.
It works for me.

12 Thierry August 12, 2011 at 2:44 am

Apparently this page doesn’t support message including any strings that can be interpreted as HTML !! so my previous message is 100% unundestandable.
Let me try it that way:
replace : send “no match : \ \n”
by : puts stderr “no match : \ \n”

Hope this time it will work

13 Thirumal Venkat August 23, 2012 at 12:43 am

in the 4th example. i think u should use send_user command instead of just send. the perl program ends after printing stuff and you are sending some input to the process even after ending. i’m having some problems on aix, then figured out that send_user outputs to the user and not the process which spawned it.

14 cliffy January 30, 2013 at 12:52 am

Hi

I need to send a string with ” part of the srting. Problem send “test “dos” ” says its invalid. Could you help me

15 abhi May 7, 2013 at 3:32 am

For script

#!/usr/bin/expect
expect “hello”
send “world”

I’m getting error

couldn’t read file “hello”: no such file or directory
expect.sh: line 3: send: command not found

16 Biju May 11, 2013 at 11:00 pm

Please help me to handle Warning Message
Password:
Warning: your password will expire in 4 days

my script automatically comes out after warning message encounters

17 Ajit June 23, 2013 at 11:40 pm

send “show running-config\r”
expect -ex ” –More– ” {send ” “}
interact

I have this code which scrolls after expecting a ” –More– ” while running the show command. I want to put the expect code in a while loop so that it would loop whenever it finds ” –More– ”

I wrote it this way
while {1} {
expect -ex ” –More– ” {send ” “}
if {expect “#”} break else continue
}

Another way I used a sample from another website:
set running 1
while {$running > 0} {
expect {
-exact ” –More– ” {send — ” “}
“#” {set running 0}
}
I am not able to make this work. Is there a way you could help me in this.

18 Rajani August 2, 2013 at 12:39 am

Its simple and very good! :) I learnt expect scripting basics from these examples.
Thanks

19 S Ravikumar October 5, 2013 at 10:25 am

Hi Sir,
I want to execute the “sas.servers status” in directory /u01/app/sas/configuration/Lev1 by using su sas.

#!/usr/bin/expect

set timeout 20

set user [lindex $argv 0]

set password [lindex $argv 1]

spawn su $user

expect “Password:”

send “$password\r”;

send “cd /u01/app/sas/configuration/Lev1\r”;

spawn “./sas.servers status”

interact
——
Its not working could you please help.

Thanks,
Ravikumar Saikam.

20 Sunil October 7, 2013 at 12:12 pm

Hi Ravi,

Try your command like this,

spawn su $user
expect “Password:”
send “$password\r”
expect “# ” # Expected prompt
send “/u01/app/sas/configuration/Lev1/sas.servers status”
interact

-Sunil

21 Anonymous December 10, 2013 at 8:38 am

hi,

I want to take the username and password in the variable and use it for doing scp/ssh.Can you help me on the same?

22 marty February 20, 2014 at 9:35 am

for the ssh login….the script below do not timeout…..how to exit when password is wrong? and something like (wrong password)

#!/usr/bin/expect
set timeout 20
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
spawn ssh “$user\@$ip”
expect “Password:”
send “$password\r”;
interact

23 Ken Florentine March 31, 2014 at 2:19 pm

if you don’t want ot worry about:
expect “yes/no)?”
Just use:
spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $user@$host
and you will not see that message anymore.

Leave a Comment

Previous post:

Next post: