Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using conditional statements inside 'expect'

I need to automate logging into a TELNET session using expect, but I need to take care of multiple passwords for the same username.

Here's the flow I need to create:

  1. Open TELNET session to an IP
  2. Send user-name
  3. Send password
  4. Wrong password? Send the same user-name again, then a different password
  5. Should have successfully logged-in at this point...

For what it's worth, here's what I've got so far:

#!/usr/bin/expect spawn telnet 192.168.40.100 expect "login:" send "spongebob\r" expect "password:" send "squarepants\r" expect "login incorrect" {   expect "login:"   send "spongebob\r"   expect "password:"   send "rhombuspants\r" } expect "prompt\>" {   send_user "success!\r" } send "blah...blah...blah\r" 

Needless to say this doesn't work, and nor does it look very pretty. From my adventures with Google expect seems to be something of a dark-art. Thanks in advance to anyone for assistance in the matter!

like image 470
shuckster Avatar asked Oct 08 '09 15:10

shuckster


2 Answers

Have to recomment the Exploring Expect book for all expect programmers -- invaluable.

I've rewritten your code: (untested)

proc login {user pass} {     expect "login:"     send "$user\r"     expect "password:"     send "$pass\r" }  set username spongebob  set passwords {squarepants rhombuspants} set index 0  spawn telnet 192.168.40.100 login $username [lindex $passwords $index] expect {     "login incorrect" {         send_user "failed with $username:[lindex $passwords $index]\n"         incr index         if {$index == [llength $passwords]} {             error "ran out of possible passwords"         }         login $username [lindex $passwords $index]         exp_continue     }     "prompt>"  } send_user "success!\n" # ... 

exp_continue loops back to the beginning of the expect block -- it's like a "redo" statement.

Note that send_user ends with \n not \r

You don't have to escape the > character in your prompt: it's not special for Tcl.

like image 131
glenn jackman Avatar answered Sep 23 '22 16:09

glenn jackman


With a bit of bashing I found a solution. Turns out that expect uses a TCL syntax that I'm not at all familiar with:

#!/usr/bin/expect set pass(0) "squarepants" set pass(1) "rhombuspants" set pass(2) "trapezoidpants" set count 0 set prompt "> " spawn telnet 192.168.40.100 expect {   "$prompt" {     send_user "successfully logged in!\r"   }   "password:" {     send "$pass($count)\r"     exp_continue   }   "login incorrect" {     incr count     exp_continue   }   "username:" {     send "spongebob\r"     exp_continue   } } send "command1\r" expect "$prompt" send "command2\r" expect "$prompt" send "exit\r" expect eof exit 

Hopefully this will be useful to others.

like image 42
shuckster Avatar answered Sep 21 '22 16:09

shuckster