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

这是我需要创建的流程:

  1. 打开与 IP 的 TELNET 会话
  2. 发送用户名
  3. 发送密码
  4. 密码错误?再次发送相同的用户名,然后发送不同的密码
  5. 此时应该已经成功登录了...

对于它的价值,这是我到目前为止所得到的:

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

不用说,这行不通,而且看起来也不太漂亮。来自我与 Google 的冒险经历 预计 似乎是一种黑暗艺术。预先感谢任何人就此事提供帮助!

有帮助吗?

解决方案

不得不推荐一下 探索期待 这本书对于所有程序员来说都是无价的。

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

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来说这并不特殊。

其他提示

经过一番抨击,我找到了解决方案。事实证明,expect 使用了我完全不熟悉的 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

希望这对其他人有用。

如果您知道用户 ID 和密码,那么您还应该知道哪些用户 ID/密码对与哪些系统一致。我认为您最好维护一张用户 ID/密码对与哪个系统对应的映射,然后提取该信息并简单地使用正确的信息。

所以——既然你显然不喜欢我的建议,那么我建议你看看 维基百科页面 并实现一个过程,如果成功则返回 0,如果期望超时则返回 1。这将允许您检测所提供的密码何时失败(提示期望超时)并重试。如果这有帮助,我已经对其进行了编辑,您可以删除您的反对票。

回想起来,您可能希望与地图一起执行此操作,因为您希望在密码更改时检测登录失败。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top