期望用于检查 ssh 连接以获取 ips 列表的脚本
Expect script for checking ssh connection for a list of ips
任何人都可以帮助我创建一个 expect 脚本来在服务器列表上执行 SSH 并检查它是否正常。我不需要交互,不需要在每个服务器上触发任何命令,我只想做一个ssh然后出来,用一个return代码来说明它是否成功。
Expect 在这里很重要,因为我没有设置无密码连接的选项。也有可能在其中一些服务器上设置了无密码连接。
我试过类似的方法:
#!/usr/local/bin/expect
set timeout 10
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
set prompt "(>|%|\\\$|#|]|) $"
spawn ssh "$user\@$ip"
expect "Password:"
send "$password\r"
send "echo hello\r"
expect "hello"
send "exit\r"
但这会卡在第一台服务器上,之后什么都不做。
谢谢,
皮尤什
一个普遍的想法可能是有一个程序来生成 ssh 并关闭连接,这将维护范围的本地连接,这样全局 spawn_id
就不会受到任何影响。
#!/usr/bin/expect
proc isHostAlive {host user pwd} {
# We escaped the `$` symbol with backslash to match literal '$'
# Commonly used prompt types
set prompt "#|%|>|\$"
set timeout 60
spawn ssh $user@$host
expect {
timeout {return FAIL}
"(yes/no)" {send "yes\r";exp_continue}
"password:" {send "$pwd\r";exp_continue}
-re $prompt
}
set msg "Hello World"
send "echo $msg\r"
expect {
timeout {return FAIL}
"\r\n$msg"
}
send "exit\r"
expect {
timeout {return FAIL}
eof
}
return PASS
}
# Lists to maintain the each host's information
set serverList {server1 server2 server3}
set userList {user1 user2 user3}
set pwdList {pwd1 pwd2 pwd3}
# Looping through all the servers and checking it's availability
foreach server $serverList user $userList pwd $pwdList {
puts "\n==>Status of $server : [isHostAlive $server $user $pwd]\n"
}
使用exp_continue
,即使任何主机没有密码,我们也可以处理。基本上 exp_continue
会导致 expect
再次变为 运行。因此,在提到的短语中,无论哪个出现,都会被处理。即如果 expect
看到 (yes/no)
,它会发送 yes
,如果 expect
看到 password
,它会发送密码值等等。然后expect会继续等待整套短语再次出现。
之所以加上yes/no
是因为假设主机的RSA指纹需要保存。
成功登录后,我正在回显Hello World
并期待回显消息。如果您注意到了,我在 expect 语句中使用了 \r\n$msg
。为什么我们需要 \r\n
这里?
原因如下。每当我们发送 expect 也会看到的命令时,它也会尝试与之匹配。如果匹配,它将照此进行。
回显命令输出示例
dinesh@dinesh-VirtualBox:~/Whosebug$ echo Hello World
Hello World
dinesh@dinesh-VirtualBox:~/Whosebug$
我们想要的字符串在send
命令中已经存在。因此,为了确保匹配的期望字符串仅来自实际的回显响应,我添加了 \r\n
这将帮助我们匹配必要的内容。
然后在 proc
的最后,我发送 exit
命令将关闭 ssh 连接并匹配使用相同的 eof
(文件结尾)。在各种失败情况下,该过程将 return FAIL
.
任何人都可以帮助我创建一个 expect 脚本来在服务器列表上执行 SSH 并检查它是否正常。我不需要交互,不需要在每个服务器上触发任何命令,我只想做一个ssh然后出来,用一个return代码来说明它是否成功。
Expect 在这里很重要,因为我没有设置无密码连接的选项。也有可能在其中一些服务器上设置了无密码连接。
我试过类似的方法:
#!/usr/local/bin/expect
set timeout 10
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
set prompt "(>|%|\\\$|#|]|) $"
spawn ssh "$user\@$ip"
expect "Password:"
send "$password\r"
send "echo hello\r"
expect "hello"
send "exit\r"
但这会卡在第一台服务器上,之后什么都不做。
谢谢, 皮尤什
一个普遍的想法可能是有一个程序来生成 ssh 并关闭连接,这将维护范围的本地连接,这样全局 spawn_id
就不会受到任何影响。
#!/usr/bin/expect
proc isHostAlive {host user pwd} {
# We escaped the `$` symbol with backslash to match literal '$'
# Commonly used prompt types
set prompt "#|%|>|\$"
set timeout 60
spawn ssh $user@$host
expect {
timeout {return FAIL}
"(yes/no)" {send "yes\r";exp_continue}
"password:" {send "$pwd\r";exp_continue}
-re $prompt
}
set msg "Hello World"
send "echo $msg\r"
expect {
timeout {return FAIL}
"\r\n$msg"
}
send "exit\r"
expect {
timeout {return FAIL}
eof
}
return PASS
}
# Lists to maintain the each host's information
set serverList {server1 server2 server3}
set userList {user1 user2 user3}
set pwdList {pwd1 pwd2 pwd3}
# Looping through all the servers and checking it's availability
foreach server $serverList user $userList pwd $pwdList {
puts "\n==>Status of $server : [isHostAlive $server $user $pwd]\n"
}
使用exp_continue
,即使任何主机没有密码,我们也可以处理。基本上 exp_continue
会导致 expect
再次变为 运行。因此,在提到的短语中,无论哪个出现,都会被处理。即如果 expect
看到 (yes/no)
,它会发送 yes
,如果 expect
看到 password
,它会发送密码值等等。然后expect会继续等待整套短语再次出现。
之所以加上yes/no
是因为假设主机的RSA指纹需要保存。
成功登录后,我正在回显Hello World
并期待回显消息。如果您注意到了,我在 expect 语句中使用了 \r\n$msg
。为什么我们需要 \r\n
这里?
原因如下。每当我们发送 expect 也会看到的命令时,它也会尝试与之匹配。如果匹配,它将照此进行。
回显命令输出示例
dinesh@dinesh-VirtualBox:~/Whosebug$ echo Hello World
Hello World
dinesh@dinesh-VirtualBox:~/Whosebug$
我们想要的字符串在send
命令中已经存在。因此,为了确保匹配的期望字符串仅来自实际的回显响应,我添加了 \r\n
这将帮助我们匹配必要的内容。
然后在 proc
的最后,我发送 exit
命令将关闭 ssh 连接并匹配使用相同的 eof
(文件结尾)。在各种失败情况下,该过程将 return FAIL
.