用于检查 SSH 可用性的服务器列表

Dol*_*yak 7 ssh shell-script

我有一个 IP 地址列表,我需要通过 SSH 连接到这些 IP 地址,如果可以访问它们,请登录。我会使用 Ping 脚本,但 DNS 可能已经重新分配了地址。我不在乎那些我无法到达的人。如果 SSH 工作,我需要记录该 IP 地址,我不必担心密码或密钥,因为我不想登录到盒子的。我只是想看看我是否可以通过 SSH 连接到他们。到目前为止,我有:

touch logfile_$(date "+%Y%m%d%T")
IP_FILE="path/to/ip_address.txt"
LOGFILE="path/to/logfile_$(date "+%Y%m%d%T")"


if [[ ! -f ${IP_FILE} ]]; then
   echo "Cannot find IP address!"
   exit 1
fi

for IP_ADDRESS in `cat $IP_FILE` ; do

    ssh $IP_ADDRESS >> $LOGFILE 2>&1
Run Code Online (Sandbox Code Playgroud)

我还是脚本的新手,任何帮助都会很棒。我看过“如何检查我是否可以通过 ssh 登录到服务器?” 由 LanceBaynes 发布,但它并不是我真正需要的。

我不能在这个盒子上安装任何东西。或者我会下载一个不错的扫描仪。像 Netcat 或 Nmap 这两个都是不错的选择。

slm*_*slm 13

方法#1:ssh-keyscan

一种方法是使用该命令ssh-keyscan查看 ssh 守护程序是否已启动并正常运行。

只需遍历 IP 地址和ssh-keyscan <ip> | grep -v ...每个服务器。如果服务器在那里,运行该ssh-keyscan ... | grep -v ...命令返回的状态将为 0,任何其他(1 或更高)表示那里没有服务器。

例子

$ for IP_ADDRESS in `cat $IP_FILE` ; do
    ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
    [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
  done
Run Code Online (Sandbox Code Playgroud)

只是为了进一步分解它,以便清楚地了解正在发生的事情,ssh-keyscan $IP_ADDRESS 2>&1将运行,返回任何输出(两者stderr&stdout合并在一起)。然后grep -v "^$"将所有这些输出通过管道传送到 ,对于返回输出的行(ssh 服务器正在运行)将返回 0,对于不返回的服务器返回 1(这"^$"是一个空行)。

循环上的快速切线(for vs. while 以及它们如何解析)

上面的循环机制(for 循环)之所以起作用,是因为文件只包含一个字符串,其中没有空格,并且每个“字符串”都以换行符结尾。默认情况下,空格是特殊的分隔符,用于指定 for 循环如何解析传递给它的参数。该字符由变量定义$IFS,可以被覆盖,例如,它是换行符 ( IFS='^M')。

您可以通过替换cat $IP_FILEwith 来提高效率$( < $IP_FILE )。例如:

$ for IP_ADDRESS in $( < $IP_FILE ) ; do
    ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
    [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
  done
Run Code Online (Sandbox Code Playgroud)

如果文件中的行$IP_FILE包含空格,您可以覆盖$IFS刚才讨论的 ,以便将其设置为 ,^M或者可以改用 while 循环,即 ( while read -ra line ; do ... ; done < $IP_FILE)。

$ while read -ra IP_ADDRESS ; do
    ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
    [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
  done < $IP_FILE
Run Code Online (Sandbox Code Playgroud)

你的榜样

touch logfile_$(date "+%Y%m%d%T")
IP_FILE="ip.txt"
LOGFILE="logfile_$(date "+%Y%m%d%T")"


if [[ ! -f ${IP_FILE} ]]; then
 echo "Cannot find IP address!"
 exit 1
fi

for IP_ADDRESS in `cat $IP_FILE` ; do
  #ssh $IP_ADDRESS >> $LOGFILE 2>&1
  ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
  [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
done
Run Code Online (Sandbox Code Playgroud)

方法#2:nmap

您还可以使用该工具做一些事情nmap

$ nmap -A -iL ip.txt -p T:22
Run Code Online (Sandbox Code Playgroud)

这将遍历文件,ip.txt其中可以包含主机名和 IP 地址,并将扫描每个人的 TCP 端口 # 22,返回类似于以下的结果:

Nmap scan report for somehost.somedom.local (192.168.1.200)
Host is up (0.012s latency).
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 4.3 (protocol 2.0)
| ssh-hostkey: 1024 2e:32:85:a2:56:23:01:f1:c2:8f:df:aa:83:7a:1e:ad (DSA)
|_2048 f6:a1:23:1d:aa:44:4a:ce:b4:d3:f4:fe:e1:00:47:b7 (RSA)
Run Code Online (Sandbox Code Playgroud)

参考

  • 为什么你使用 `for` 和 `cat` 而不是 `while` 和 `&lt;`? (2认同)