我正在尝试使用测试用户列表和使用 bash 的主机列表来编写 SSH 连接测试脚本,你能帮忙吗?

我正在尝试使用测试用户列表和使用 bash 的主机列表来编写 SSH 连接测试脚本,你能帮忙吗?

我正在尝试使用一组相应的测试用户帐户来测试一组主机的 ssh 连接。

即:testuser1 test ssh connection to server1testuser2 test ssh connection to server2testuser3 test ssh connection to server3等。

每个测试用户都使用私钥登录: ssh -i ~/keys/testuser1key testuser1@server1

但是,当我将此信息放入变量时遇到了问题。这是到目前为止我所拥有的脚本:

for host in $(cat hosts)
do
   if
      ssh -i $host 'true' exit
   then
      echo "SSH connection for $host ok"
   else
      echo "SSH connection for $host failed"
   fi
done
$SHELL

host文件如下所示:

~/keys/testuser1key testuser1@server1
~/keys/testuser2key testuser2@server2
~/keys/testuser3key testuser3@server3
...

我收到错误,例如could not resolve hostname true

我认为文件中的空格host是破坏脚本的原因。我使用了类似的脚本,在运行我的用户帐户时没有问题,并且没有“-i”ssh 标志。 ( ssh myuseraccount@testserver1)

任何有关更好方法的帮助或建议都将受到赞赏!

答案1

我建议使用while read循环,以便您可以将空格分隔的标记分配给各个变量,而不是依赖于隐式 split+glob 行为$(cat hosts)

唯一棘手的一点是read默认情况下从标准输入读取 - 也是如此ssh。因此,您需要传递标志-n来告诉 ssh 从 /dev/null 读取:

while read -r identityfile host; do
  if ssh -n -i "$identityfile" "$host" true
  then
    echo "SSH connection for $host ok"
  else
    echo "SSH connection for $host failed"
  fi
done < hosts

或告诉read从不同的文件描述符读取:

while read -u3 -r identityfile host; do
  if ssh -i "$identityfile" "$host" true
  then
    echo "SSH connection for $host ok"
  else
    echo "SSH connection for $host failed"
  fi
done 3< hosts

~注意:您通过使用而不是$HOME为主机文件的身份文件部分添加前缀,使事情变得有些困难。引用"$identityfile"可防止 shell 进行波形符扩展;然而离开它联合国引用 (as $identityfile) 是危险的,因为它允许分词和文件名生成1。它似乎至少 OpenSSH 实现可以ssh扩展~自身,但如果您的 ssh 实现没有扩展,则需要额外的处理才能正确处理它。

1在这种情况下,文件名生成(通配符)是主要关注的问题,因为如果名称包含空格,则整个方法就有缺陷。

相关内容