Expect脚本,用于检查ssh连接以获取ips列表 [英] Expect script for checking ssh connection for a list of ips

查看:304
本文介绍了Expect脚本,用于检查ssh连接以获取ips列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以帮助我创建一个期望脚本,以便仅在服务器列表上执行SSH并检查是否正常.我不需要进行交互,不需要在每个服务器上触发任何命令,我只想执行ssh并显示出来,并带有返回代码,说明该操作是否成功.

Can anyone help me in creating an expect script to just do an SSH on a list of servers and check if it was fine. I do not need to interact, do not need to fire any command on each server, I just want to do an ssh and come out, with a return code mentioning whether it was successful or not.

这里的期望很重要,因为我没有设置无密码连接的选项.还有可能在其中一些服务器上建立无密码连接.

Expect is important here, as I do not have an option to setup a passwordless connection. Also there is a possibility that passwordless connection is setup on some of those servers.

我尝试过类似的事情:

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

但是这卡在第一台服务器上,此后什么也不做.

But this gets stuck on the first server, and does nothing after that.

谢谢, 皮尤什

推荐答案

一个通用的想法可能是产生一个ssh并关闭连接的过程,该过程将使连接保持在作用域本地,从而赢得了全局spawn_id完全不会受到影响.

A generalized idea can be having a procedure to spawn the ssh and close the connection which will maintain the connections local to the scope, so that global spawn_id won't get affected at all.

#!/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,则将发送密码值,依此类推.然后期望将继续继续等待整个短语.

With exp_continue, we can handle even if any host does not have password. Basically exp_continue will cause the expect to run again. So, among the mentioned phrase whichever comes, it will be handled. i.e. if expect sees (yes/no), it will send yes, if expect sees password, it will send the password value and so on. Then expect will continue to wait for the whole set of phrases again.

我添加yes/no的原因是因为如果假设需要保存主机的RSA指纹,请执行以下操作.

The reason why I have added yes/no is because if suppose the host's RSA fingerprint needs to be saved.

成功登录后,我回显Hello World并期望收到回显的消息.如果您已经注意到,我在Expect语句中使用了\r\n$msg.为什么我们在这里需要\r\n?

After successful login, I am echoing Hello World and expecting for the echoed message. If you have noticed, I have used \r\n$msg in the expect statement. Why do we need \r\n here ?

这就是原因.每当我们发送期望也会看到的命令时,它也会尝试与此匹配.如果匹配,它将照此进行.

Here is why. Whenever we send command that will be seen by the expect also and it will try to match against that too. If it matched, it will proceed as such.

示例回显命令输出

dinesh@dinesh-VirtualBox:~/stackoverflow$ echo Hello World
Hello World
dinesh@dinesh-VirtualBox:~/stackoverflow$ 

我们期望的字符串已经在send命令中可用.因此,为确保匹配的期望字符串仅来自实际的回显响应,我添加了\r\n,这将帮助我们进行必要的匹配.

The string we want to expect is already available in the send command. So, to make sure the matching expect string is only from the actual echoed response, I have added \r\n which will help us in matching what is necessary.

然后在proc的最后,我发送exit命令,该命令将关闭ssh连接并匹配使用相同的eof(文件末尾).在所有失败情况下,该过程都将返回FAIL.

Then at last of the proc, I am sending exit command which will close the ssh connection and to match the same eof (End Of File) is used. In all sort of failure cases, the procedure will return FAIL.

这篇关于Expect脚本,用于检查ssh连接以获取ips列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆