BASH – Automating SCP/SSH/RSYNC connections with EXPECT

Published on Author gryzliLeave a comment

Very often I need to automate some task which requires user input, most of the times this input is some type of credentials (user + password) or sometime some more.

I have find that expect is very useful in such cases.

 

Before trying any of the scripts below, make sure you have expect installed on your system. Most of the time installing expect is as simple as doing “zypper/yum/apt-get install expect”.

 

Here are some simple expect scripts which can be used to automate SSH/rsync/scp  connections by providing them with credentials.

 

Executing batch SSH commands with password authentication using expect

First create the expect script file called: ssh.exp 

#!/usr/bin/expect -f
# THIS SCRIPT IS USED FOR BATCH SSH LOGIN/RSYNC
# THROUGH BASH SCRIPT
# ###################

# check for supplied arguments
if {[llength $argv] == 0} {
  send_user "Usage: scriptname destination_ip destination_port destination_user "
  send_user "destination_password ssh_command \n"
  exit 1
}

set destination_ip              [lindex $argv 0 ]
set destination_port            [lindex $argv 1 ]
set destination_user            [lindex $argv 2 ]
set destination_password        [lindex $argv 3 ]
set ssh_command                 [lindex $argv 4 ]


set timeout -1
#### Local vars
set host 127.0.0.1


#### Execute SSH command
spawn ssh -p $destination_port -o "StrictHostKeyChecking no" $destination_user@$destination_ip "$ssh_command"
        match_max 100000 ;
        expect -re ".*assword.*" ;
        send -- "$destination_password\r" ;
        send -- "\r" ;
        expect eof ;

 

Second, set some execute permissions on the file:

chmod u+x ssh.exp

Finally you can run the script with the following usage:

./ssh.exp IP SSH_PORT SSH_USER SSH_PASS SSH_COMMAND

Here some example with values, which will execute “uptime” with root user on a host 192.168.1.1

./ssh.exp 192.168.1.1 22 root root_pass "uptime" 

 

Executing batch rsync with password authentication using expect

First create the expect script file called: rsync.exp 

#!/usr/bin/expect -f
# THIS SCRIPT IS USED FOR BATCH RSYNC
# THROUGH BASH SCRIPT
# ###################
 
# check for supplied arguments
if {[llength $argv] == 0} {
  send_user "Usage: scriptname local_path destination_path ssh_port ssh_password "
  exit 1
}
 
 
set local_path                  [lindex $argv 0 ]
set destination_path            [lindex $argv 1 ]
set destination_port            [lindex $argv 2 ]
set destination_password        [lindex $argv 3 ]
 
set timeout -1
#### Local vars
set host 127.0.0.1
 
 
#### Execute SSH command
spawn rsync -av "--progress" -e " ssh -p $destination_port -o 'StrictHostKeyChecking=no'" $local_path $destination_path
        match_max 100000 ;
        expect -re ".*assword.*" ;
        send -- "$destination_password\r" ;
        send -- "\r" ;
        expect eof ;

 

Second, set some execute permissions on the file:

chmod u+x rsync.exp

Finally you can run the script with the following usage:

– This will copy current /root/work/ content to the destination one

./rsync.exp /root/work/ root@192.168.1.1:/root/work/ "ssh_port" "ssh_password"

or you could try the oposite:

./rsync.exp root@192.168.1.1:/root/work/ /root/work/ "ssh_port" "root_password"

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *