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"