在'expect'中使用条件语句

时间:2009-10-08 15:08:49

标签: bash automation telnet expect conditional-statements

我需要使用 expect 自动登录到TELNET会话,但是我需要为同一个用户名处理多个密码。

以下是我需要创建的流程:

  1. 打开到IP的TELNET会话
  2. 发送用户名
  3. 发送密码
  4. 密码错误?再次发送相同的用户名,然后使用不同的密码
  5. 此时应该已成功登录...
  6. 对于它的价值,这是我到目前为止所得到的:

    #!/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"
    

    毋庸置疑,这不起作用,也看起来不漂亮。从我与谷歌的冒险期待似乎是一种黑暗艺术。在此事先感谢任何人的帮助!

3 个答案:

答案 0 :(得分:36)

必须为所有期望程序员推荐Exploring Expect本书 - 非常宝贵。

我重写了你的代码:(未经测试)

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循环回到expect块的开头 - 它就像一个“重做”语句。

请注意,send_user\n而不是\r

结尾

您不必在提示符中转义>字符:它对Tcl并不特殊。

答案 1 :(得分:11)

经过一番抨击,我找到了解决方案。事实证明,期望使用我并不熟悉的TCL语法:

#!/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

希望这对其他人有用。

答案 2 :(得分:-1)

如果您知道用户ID和密码,那么您还应该知道哪些用户ID /密码对与哪些系统对齐。我认为你最好维护一个用户名/密码对与哪个系统一起提取该信息并使用正确信息的地图。

所以 - 既然你显然不喜欢我的建议,那么我建议你看看wikipedia page并实现一个程序,如果成功则返回0,如果期望超时则返回1。这将允许您检测提供的密码何时失败 - 提示期望超时 - 然后重试。如果这有用,您可以在我编辑它之后删除您的downvote。

回想起来,你可能想要与地图一起做这件事,因为如果密码被更改你想要检测失败的登录。