在another question中他们善意地为我提供了一个解决方案,解决了我在使用 Expect 和 if/else 语句时遇到的困境(基本上,我对它们的编写方式缺乏了解)。我收到的脚本有一个异常(exception):如果我干净地连接到远程主机,则不会发送 exit
命令,这将关闭该连接并移至列表中的下一个主机。
这是脚本的功能部分:
while {[gets $file1 host] != -1} {
puts $host
spawn -noecho ssh $host
expect {
"continue connecting" {
send "yes\r"
expect {
"current" {
send -- $pw2\r
exp_continue
}
"New password" {
send -- $pw1\r
exp_continue
}
"Retype new password" {
send -- $pw1\r
exp_continue
}
msnyder
}
send "exit\r"
}
}
interact
}
当我连接到主机时,我希望看到标准的 Linux 提示符:[username@host ~]$。至少,这是我们的标准提示。提示前面有一个横幅。这可能会让事情变得棘手吗?我不这么认为,因为我只是从 RSA 指纹提示中寻找“继续连接”,并且该提示位于跨多行的文本中。我认为 Expect 足够智能,可以忽略任何滚动文本,而只查看正在寻找输入的提示中的文本。
我考虑过将 exit
命令作为 ssh $host
命令的参数传递,但 Expect 似乎不喜欢这样。
有人现在可以帮助我正确发送 exit
命令吗?
更新:我已将 exp_internal 1
选项添加到脚本中以查看它在做什么,并且即使在 SSH 连接后出现用户提示,它似乎也只会匹配“继续连接”成立。它似乎没有执行“msnyder”的下一个比较。 http://pastebin.com/kEGH3yUY
更新2:我正在取得进展。基于Glenn Jackman在下面的脚本中,我能够使其正常工作,直到出现密码提示:
set prompt {\$ $}
set file1 [open [lindex $argv 0] r]
set pw1 [exec cat /home/msnyder/bin/.pw1.txt]
set pw2 [exec cat /home/msnyder/bin/.pw2.txt]
while {[gets $file1 host] != -1} {
puts $host
spawn -noecho ssh -q $host
expect {
"continue connecting" {
send "yes\r"
expect {
"current" {
send -- $pw2\r
exp_continue
}
"New password" {
send -- $pw1\r
exp_continue
}
"Retype new password" {
send -- $pw1\r
exp_continue
}
-re $prompt {
send -- exit\r
expect eof
}
}
} -re $prompt {
send -- exit\r
expect eof
}
}
}
我已明确告诉它发送退出命令两次,而不是尝试格伦使用的短路方法(根据我在他的回答下的评论,它似乎不起作用)。
现在发生的情况是,它将循环遍历主机列表,向 RSA 指纹提示符发送“yes”,然后向命令提示符发送“exit”。但是,当它到达需要设置密码的服务器时,它就会停止。它似乎最终超时,然后与下一个主机重新启动。未发送当前密码。
最佳答案
# a regular expression that matches a dollar sign followed by a space
# anchored at the end of the string
set prompt {\$ $}
while {[gets $file1 host] != -1} {
puts $host
spawn -noecho ssh $host
expect {
"continue connecting" {
send "yes\r"
expect {
# ...snipped...
-re $prompt
}
}
-re $prompt
}
send -- exit\r
expect eof
}
我们已将“退出”移动到一个位置,如果您匹配“继续连接”或直接登录到提示符,它将被执行。
很好的答案,但我讨厌看到代码被剪切和粘贴。一条评论和一点重构:当您点击“当前” block 时,您会更改密码但永远不会退出。似乎每个场景都应该以您看到提示并退出而结束:
while {[gets $file1 host] != -1} {
puts $host
spawn -noecho ssh -q $host
expect {
"continue connecting" {
send "yes\r"
exp_continue
}
"current" {
send -- $pw2\r
expect "New password"
send -- $pw1\r
expect "Retype new password"
send -- $pw1\r
exp_continue
}
-re $prompt
}
send -- exit\r
expect eof
}
如果您看到“继续连接”,请发送"is",然后等待看到“当前”或提示。
如果您看到“当前”,则更改密码,然后等待看到提示。
如果您看到提示,则预期注释结束,您要做的下一步就是退出。
关于ssh - 使用expect脚本通过SSH发送命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18663218/