在another question中,我得到了一个解决我遇到的困境的解决方案和if / else语句(基本上,我对他们的写作方式缺乏了解)。我给出的脚本有一个例外:如果我干净地连接到远程主机,则不会发送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指纹提示中寻找“继续连接”,这是在跨越多行的文本内。我认为期望足够聪明,可以忽略任何滚动文本,只查看正在寻找输入的提示中的文本。
我考虑将exit
命令作为ssh $host
命令的参数传递,但是期望似乎不喜欢这样。
现在有人可以协助我正确发送exit
命令吗?
更新:我已经在脚本中添加了exp_internal 1
选项以查看它正在做什么,并且在建立SSH连接后,即使在用户提示下,它似乎也只是匹配“继续连接”。它似乎没有执行“msnyder”的下一个比较。 http://pastebin.com/kEGH3yUY
UPDATE2:我正在取得进展。根据下面的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指纹提示发送“是”,然后将“退出”发送到命令提示符。但是,当它遇到需要设置密码的服务器时,它会停止。它似乎最终超时,然后重新启动与下一个主机。当前密码未发送。
答案 0 :(得分:1)
# 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
}
如果你匹配“comtinue连接”或直接登录到你的提示,我们已经将“退出”移动到将被执行的地方。
很好的答案,但我讨厌看到代码剪切和粘贴。一条评论和一些重构:当您点击“当前”块时,您更改了密码但从未退出。它应该是每个场景应该以您看到提示并退出:
结束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
}
如果您看到“继续连接”,则发送“是”,然后等待查看“当前”或提示 如果您看到“当前”,则更改密码,然后等待查看提示 如果你看到提示,那么期望评论就会结束,你接下来要做的就是退出。
答案 1 :(得分:1)
我已经找到了答案。在看下面的Glenn脚本之后,我发现每个块都是一个单独的if / else而不是我需要密码部分作为单个块而退出作为else。这就是我现在拥有的:
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 {
-re $prompt {
send -- exit\r
expect eof
}
"current" {
send -- $pw2\r
expect "New password"
send -- $pw1\r
expect "Retype new password"
send -- $pw1\r
}
"continue connecting" {
send "yes\r"
expect {
"current" {
send -- $pw2\r
expect "New password"
send -- $pw1\r
expect "Retype new password"
send -- $pw1\r
}
-re $prompt {
send -- exit\r
expect eof
}
}
}
}
}
它解决了四种情况: