Using conditional statements inside 'expect'

前端 未结 3 954
感情败类
感情败类 2020-12-01 05:27

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

相关标签:
3条回答
  • 2020-12-01 05:54

    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.

    0 讨论(0)
  • 2020-12-01 05:54

    If you know the user ids and passwords, then you ought also to know which userid/password pairs are aligned with which systems. I think you'd be better off maintaining a map of which userid/password pair goes with which system then extracting that information and simply use the correct one.

    So -- since you obviously don't like my advice, then I suggest you look at the wikipedia page and implement a procedure that returns 0 if successful and 1 if the expectation times out. That will allow you to detect when the password supplied failed -- the prompt expectation times out -- and retry. If this is helpful, you can remove your downvote now that I've edited it.

    In retrospect, you'd probably want to do this in conjunction with the map anyway since you'd want to detect a failed login if the password was changed.

    0 讨论(0)
  • 2020-12-01 06:03

    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.

    0 讨论(0)
提交回复
热议问题