Link to home
Start Free TrialLog in
Avatar of drj003
drj003

asked on

Expect script that utilizes SSH on multiple systems

I'm trying to use an expect script that logs into numerous systems and checks for the kernel version.  The script works except for when it gets to a system that it has the wrong password for.  Instead of skipping the system, the script errors out.  I'm not very experienced with expect and could use some assistance.

Thanks



#!/usr/bin/expect

set timeout 10
set prompt "(#|root#|$|jsmith$) $"
set file [open ./filelist r]
set servers [read -nonewline $file]
close $file

stty echo


send_user "\nEnter user id: "
expect_user -re "(.*)\n" {set userid $expect_out(1,string)}
send_user "\nEnter Password: "

stty -echo

expect_user -re "(.*)\n" {set pword $expect_out(1,string)}

stty echo

foreach host [split $servers "\n"] {

spawn ssh -o StrictHostKeyChecking=no $userid@$host


expect {
  "assword:" { send -- "$pword\n"}
  "Permission denied, please try again." {  send -- "$pword\n"}
}
  expect -re "$prompt"
  send -- "uname -r\n"
  expect -re "$prompt"
  send -- "echo All Done\n"
  expect -re "$prompt"
  send -- "exit\n"

}
Avatar of woolmilkporc
woolmilkporc
Flag of Germany image

Instead of sending the password again:

  "Permission denied, please try again." {  send -- "$pword\n"}

you could continue with the next iteration:

  "Permission denied, please try again." {  continue }
Avatar of drj003
drj003

ASKER

Thanks for the reply.

I changed it to

  "Permission denied, please try again." {  continue }

This was the result when it hit a system that it had the wrong password for-



 
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
send: spawn id exp8 not open
    while executing
"send -- "exit\n""
    ("foreach" body line 15)
    invoked from within
"foreach host [split $servers "\n"] {

spawn ssh -o StrictHostKeyChecking=no $userid@$host


expect {
  "assword:" { send -- "$pword\n"}
  "Permission ..."
    (file "./kernelcheck" line 22)




Thanks
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
That's not the same message as posted in the Q. Please adjust.
Avatar of drj003

ASKER

I may be misunderstanding, but that was the output after I changed it to continue with the next iteration, instead of sending the password again.  Should I still adjust?
Avatar of drj003

ASKER

I want the script to skip any server it has the wrong password for, and move on to the next server in the list.
Try "break" instead of continue.
Avatar of drj003

ASKER

changing it to break didn't go past the server with the wrong password either.

so the script in it's current state is (output is below the script)-




**********************************************************************
#!/usr/bin/expect

set timeout 10
set prompt "(#|root#|$|jsmith$) $"
set file [open ./filelist r]
set servers [read -nonewline $file]
close $file

stty echo


send_user "\nEnter user id: "
expect_user -re "(.*)\n" {set userid $expect_out(1,string)}
send_user "\nEnter Password: "

stty -echo

expect_user -re "(.*)\n" {set pword $expect_out(1,string)}

stty echo

foreach host [split $servers "\n"] {

spawn ssh -o StrictHostKeyChecking=no $userid@$host


expect {
  "assword:" { send -- "$pword\n"}
  "Permission denied, please try again." { break }
}


expect -re "$prompt"
send -- "uname -r\n"
expect -re "$prompt"
send -- "echo All Done\n"
expect -re "$prompt"
send -- "exit\n"

}


**********************************************************************



The output from the above script-

*********************************************************************






root#./kernelcheck

Enter user id: root

Enter Password: spawn ssh -o StrictHostKeyChecking=no root@rv-poc-josh-01
root@rv-poc-josh-01's password:
Last login: Wed Mar 12 16:42:14 2014 from 10.3.102.199
[root@rv-poc-josh-01 ~]# uname -r
2.6.39-400.17.2.el6uek.x86_64
[root@rv-poc-josh-01 ~]# echo All Done
All Done
[root@rv-poc-josh-01 ~]# spawn ssh -o StrictHostKeyChecking=no root@rv-poc-josh-02
root@rv-poc-josh-02's password:
Last login: Wed Mar 12 16:42:17 2014 from 10.3.102.199
[root@rv-poc-josh-02 ~]# uname -r
2.6.39-400.17.2.el6uek.x86_64
[root@rv-poc-josh-02 ~]# echo All Done
All Done
[root@rv-poc-josh-02 ~]# spawn ssh -o StrictHostKeyChecking=no root@rv-poc-josh-03
root@rv-poc-josh-03's password:
Permission denied, please try again.
root@rv-poc-josh-03's password:
Permission denied, please try again.
root@rv-poc-josh-03's password:
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
send: spawn id exp8 not open
    while executing
"send -- "exit\n""
    ("foreach" body line 17)
    invoked from within
"foreach host [split $servers "\n"] {

spawn ssh -o StrictHostKeyChecking=no $userid@$host


expect {
  "assword:" { send -- "$pword\n"}
  "Permission ..."
    (file "./kernelcheck" line 22)
***********************************************************************
Could it be that the server with the wrong password is the last one in the list?

Under normal circumstances expect should iterate anyway once a non-matching prompt is encountered (and the timeout has passed).
Avatar of drj003

ASKER

It's the 3rd server out of 4.
ASKER CERTIFIED SOLUTION
Avatar of woolmilkporc
woolmilkporc
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This is an aside from your direct issue.

You might just want to use ssh keys on your accounts so that you don't have to write this script to prompt you for a password for each connection.  If you use ssh keys, you'd only need to start ssh-agent and enter your passphrase one time after you add your key with ssh-add, then ssh will take care of the rest.
OK, I finally found a server which seems to react the same way as yours.
Here is my solution:

...
spawn ssh -o StrictHostKeyChecking=no $userid@$host
expect_after eof {
catch {close -i $spawn_id}
wait -nowait -i $spawn_id
continue ;
}


expect {
  "assword:" { send -- "$pword\n"}
}


expect -re "$prompt"
send -- "uname -r\n"
expect -re "$prompt"
send -- "echo All Done\n"
expect -re "$prompt"
send -- "exit\n"
expect eof
}
Avatar of drj003

ASKER

When you said it automatically disconnects, it lead me remove

send -- "exit\n" from the script and it worked.

Thanks
Avatar of drj003

ASKER

Oh, I didn't see your last post before I responded.  I'll try that too.

Thanks again.