2

I have an expect script which performs an SSH to a list of servers with the credentials mentioned in the script. It is not throwing any error when it is unable to SSH to a particular server and continues with the next server in the list. I want the script to let me know when it is unable to SSH with the password given. What changes should be made to the script to get this done?

The first script is a shell script which calls the expect script

#!/usr/bin/ksh
for host_name in `cat list`
do
    /home/user1/ssh_script $host_name
done

#!/usr/local/bin/expect -f
set timeout 1
set host_name [lindex $argv 0]
spawn ssh -q -o StrictHostKeyChecking=no "user1\@$host_name"
expect "*assword:"
send "abcd@123\r";
expect "$\r"
puts "user1 loggedin successfully"
exit
interact
meuh
  • 51,383

1 Answers1

3

You can match for a timeout "pattern" in the expect lines. For example,

#!/usr/bin/expect -f
proc abort { } { send_user "Timeout!" ; exit 2 }
set timeout 1
set host_name [lindex $argv 0]
spawn ssh -q -o StrictHostKeyChecking=no "user1\@$host_name"
expect timeout abort "assword:"
send "abcd@123\r"
expect timeout abort "assword: " { send_user "bad password\n"; exit 3 } "$\r"
puts "user1 loggedin successfully"

This adds a one line procedure abort to the start, and the pattern+action sequence timeout abort to each expect. This will call the procedure if the expect times out. The procedure writes a string to stdout and exits with return code 2 instead of the default 0. You can test for this exit code in your ksh script if you want to.


To detect a bad login password, you can look for a second prompt for the password at the same time as looking for the "$" prompt showing you have logged in ok.

meuh
  • 51,383
  • I modified the script like above in expect ssh script. It is giving the below error. invalid command name "abort" while executing "abort { } { send_user "Timeout!" ; exit 2 }" – Su_scriptingbee Jan 17 '17 at 10:36
  • Oops. I'm sorry, I left out the keyword proc on the 2nd line when copying the program. I've edited the answer with this fix. – meuh Jan 17 '17 at 12:34
  • "Timeout!" is displayed for all servers(including those whose password is different) in the list with this script. – Su_scriptingbee Jan 17 '17 at 15:36
  • I'm not surprised. I would use a timeout of at least 5 seconds for ssh. Perhaps even more will be needed as ssh startup can be quite slow. – meuh Jan 17 '17 at 15:40
  • Increased the time out value to 15 sec and the message "Timeout!" appears to all the servers – Su_scriptingbee Jan 18 '17 at 10:29
  • Are you sure the second pattern you look for, "$\r" is correct? Normally, a shell prompt would be something like " $" or "$ " or even just "$". – meuh Jan 18 '17 at 14:02
  • with or with out \r in second pattern, am getting the same output – Su_scriptingbee Jan 18 '17 at 14:54
  • How can I get the exit status of a spawned process. By using that, i want to find out to which server SSH is not successful. – Su_scriptingbee Jan 18 '17 at 15:02
  • To detect a bad password you can check for a second Password: prompt; I've edited my answer to show how. If you have a bad hostname the spawn will fail and expect with fail with exit code 1 on the send command. You can also get lots of debug by replacing -f in the first line by -d. – meuh Jan 18 '17 at 15:53
  • The script is giving me the desired output now. Thanks a lot! – Su_scriptingbee Jan 19 '17 at 15:20
  • Being a noob in expect scripting, could you please confirm on my below insights:

    1.)The spawned process is exiting after throwing the message bad password when it encouters password: prompt for second time.

    2.)combining two commands "send_user" and "exit" is done by using flower braces {}.

    3.)For servers in which SSH works fine, does the expect line with password: (2nd time) is skipped?

    – Su_scriptingbee Jan 19 '17 at 16:32
  • Yes to 1 and 2. For 3, the expect is looking simultaneously for any of three matches: a timeout, the string "assword: ", and the string "$\r". So when the ssh login works ok, it will match the "$\r", and so continue to the next command, as no action was specified for this match. – meuh Jan 19 '17 at 17:32
  • Hi Meuh. I want to further enhance my script with one one more case.If server is powered off or down, it should say "Due to some reason, ssh did not happen. I modified it like this. – Su_scriptingbee Feb 02 '17 at 11:34
  • Start a new Post. – meuh Feb 02 '17 at 11:42