我正在尝试使用一组相应的测试用户帐户来测试一组主机的 ssh 连接。
即:testuser1 test ssh connection to server1
、testuser2 test ssh connection to server2
、testuser3 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在这种情况下,文件名生成(通配符)是主要关注的问题,因为如果名称包含空格,则整个方法就有缺陷。