【问题标题】:script to check if I can access multiple servers检查我是否可以访问多个服务器的脚本
【发布时间】:2018-09-08 21:32:13
【问题描述】:

我制作了这个脚本来检查我是否可以连接到许多服务器的列表:

for SERVER in $(cat servers.txt); do
ssh root@$SERVER && echo OK $SERVER || echo ERR $SERVER
done

问题是,如果是我第一次连接到服务器,服务器会问经典问题“The authenticity of host ‘x.x.x.x’ can't be established... bla bla bla”然后我必须回答是或否,它失去了让它成为脚本的目的,有什么办法可以绕过它,以便我可以将其添加到脚本中?

另外,有些服务器中我没有我的密钥,但他们可以选择输入密码。在这种情况下,它会等到我尝试输入密码才能继续执行脚本,所以我想知道是否有办法改进这个脚本,所以如果服务器要求输入密码,然后将其设置为 ERR $SERVER 并继续脚本?

感谢您的帮助。

【问题讨论】:

  • ssh 没有要执行的命令将启动交互式登录会话。您需要发送类似ssh root@$SERVER true 的命令。
  • @Barmar 谢谢Barman,我也在寻找这个选项。
  • 使用while 循环遍历服务器列表,而不是for 循环。 while IFS= read -r SERVER; do ...; done < servers.txt.
  • sshpass 可用于传递密码。另外,如果可能的话,您可能想尝试 python 和 paramiko 模块

标签: bash ssh scripting openssh


【解决方案1】:

您可以使用 -o 标志在 SSH 中设置选项:

for SERVER in $(cat servers.txt); do
  ssh -o StrictHostKeyChecking=no -o BatchMode=yes root@$SERVER exit && echo OK $SERVER || echo ERR $SERVER
done

查看 ssh_config 的联机帮助页:man ssh_config 以了解 -o 标志可用的所有选项。

【讨论】:

  • 酷,我喜欢你的回答,但是,我仍然缺少密码部分:(
  • @VaTo 使用禁用询问密码的选项
  • 您可能需要考虑打开批处理模式以跳过密码验证:-o BatchMode=yes 我已更新答案以包含该选项。还在 ssh 命令的末尾添加了exit,以便在成功连接时退出会话。正如@Barmar 在问题的 cmets 中建议的那样,您也可以使用true。就这样执行某些操作并关闭 ssh 会话。
  • 我做了ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no root@$SERVER true && echo OK $SERVER || echo ERR $SERVER 并且成功了。它们之间有什么区别吗?
  • @VaTo 我不确定那个。我认为 Batchmode 在一个设置中将几个选项结合在一起,但不要引用我的话。
【解决方案2】:

如果您有很多服务器,您可能想做的是同时连接到所有服务器。这样,如果任何服务器无响应,它最多只等待 2 分钟(默认 TCP connect 超时)。

在不分配终端的情况下连接到每个服务器并执行echo . 命令,将输出重定向到命名文件中。在循环中异步发出这些命令。然后wait 直到所有命令完成,遍历日志文件并检查哪些文件中有点。然后报告其日志文件中没有点的服务器。

例如:

#/bin/bash

servers="$@"

for server in $servers; do
    ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -Tn $server echo . >$server.log 2>$server.error.log &
done
wait # After 2 minutes all connection attempts timeout.
for server in $servers; do
    [[ -s $server.log ]] || echo "Failed to connect to $server" >2
done

【讨论】:

    【解决方案3】:

    您真的需要建立 SSH 连接吗?

    或者只是在 SSH 端口上打开一个到主机的套接字连接足以让您确定服务器在线?

    servers.txt

    hostA.example.com
    hostB.example.com
    hostC.example.com
    

    port-probe.sh

    #!/bin/bash
    
    PORT=22
    TIMEOUT=3
    for SERVER in $(cat servers.txt); do
    
        # Open a socket and send a char
        echo "-" | nc -w $TIMEOUT $SERVER $PORT &> /dev/null
    
        # Check exit code of NC
        if [ $? -eq 0 ]; then
    
            echo "$SERVER is Available."
        else
    
            echo "$SERVER is Unavailable."
        fi
    done
    

    【讨论】:

    • Matt 我知道服务器在线,但我想做的只是知道我的密钥是否已添加到服务器。
    猜你喜欢
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    • 2018-12-15
    相关资源
    最近更新 更多