Sample Expect Script

Expect is a programming language for automating systems which expose interactive text terminal such as telnet, ssh, ftp, scp etc,. It is extension to Tcl language. It is created by Don Libes.

In this post I will share you sample expect script, which connects list of servers over ssh, executes command and prints it out on the screen.

Install Package

To use Expect language (It is actually a programming language–Extension of Tcl.), we need to install expect package.

#For CentOS and RedHat
[root@rhce ~]# yum install expect
#For Ubuntu, Debian and Mint
gns3@gns3:~/Programs$ sudo apt-get install expect

Create a server list.

Create a serverlist.txt file and put your server’ IP address or Domain names in this file line by line.  You can see below sample file contents.

gns3@gns3:~/Programs$ cat serverlist.txt 
192.168.59.133
192.168.59.134

Create Expect Script.

You can use below sample script and tweak it for your own purpose. For this script I have servers, username demo and password is demo

#!/usr/bin/expect -f
set fd "serverlist.txt"
set fp [open "$fd" r]
set data [read $fp]
 
# Read line by line
set timeout 15
 
foreach server $data {
puts "================ssh for $server============================"
 
 spawn ssh -l demo "$server"
 expect "password: "
 send "demo\r"
 expect "$ "
 send "uptime\r"
 expect "$ "
 send "ifconfig\r"
 expect "$ "
 send "exit\r"
}

Experiment

I actually have only one virtual machine (192.168.59.133) second machine (192.168.59.134) is an artificial. It is added for the sake of  for-loop demonstration.

gns3@gns3:~/Programs$ expect exp.exp 
================ssh for 192.168.59.133============================
spawn ssh -l demo 192.168.59.133
demo@192.168.59.133's password: 
Last login: Sat Jul 22 10:24:05 2017 from 192.168.59.10
[demo@rhce ~]$ uptime
10:26:20 up 19:46, 3 users, load average: 0.51, 0.14, 0.08
[demo@rhce ~]$ ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.59.133 netmask 255.255.255.0 broadcast 192.168.59.255
inet6 fe80::501e:8a2:2c44:a64 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:81:06:9a txqueuelen 1000 (Ethernet)
RX packets 162104 bytes 201013659 (191.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 70217 bytes 4834892 (4.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1 (Local Loopback)
RX packets 8 bytes 440 (440.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 440 (440.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
ether 52:54:00:08:7f:61 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

[demo@rhce ~]$ ================ssh for 192.168.59.134============================
spawn ssh -l demo 192.168.59.134
ssh: connect to host 192.168.59.134 port 22: No route to host
send: spawn id exp8 not open
while executing
"send "demo\r""
("foreach" body line 6)
invoked from within
"foreach server $data {
puts "================ssh for $server============================"

spawn ssh -l demo "$server"
expect "password: "
send "d..."
(file "exp.exp" line 9)

 

That is all for now. Happy expecting. 🙂