我正在尝试使用一组相应的测试用户帐户来测试一组主机的 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
Run Code Online (Sandbox Code Playgroud)
该host
文件如下所示:
~/keys/testuser1key testuser1@server1
~/keys/testuser2key testuser2@server2
~/keys/testuser3key testuser3@server3
...
Run Code Online (Sandbox Code Playgroud)
我收到错误,例如 could not resolve hostname true
我认为host
文件中的空间是破坏脚本的原因。我在运行我的用户帐户时使用了一个类似的脚本,没有问题,并且没有“-i”ssh 标志。( ssh myuseraccount@testserver1
)
任何关于更好的方法的帮助或建议表示赞赏!
我建议使用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
Run Code Online (Sandbox Code Playgroud)
或告诉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
Run Code Online (Sandbox Code Playgroud)
注意:您通过使用~
而不是$HOME
例如为主机文件的身份文件部分添加前缀使事情变得有些困难。引用"$identityfile"
可以防止 shell 的波浪号扩展;但是不加引号(as $identityfile
)是危险的,因为它允许分词和文件名生成1。这似乎是的,至少OpenSSH的实现ssh
扩张~
本身,但如果你的SSH实现没有,那么将需要额外的处理,以妥善处理。
1在这种情况下,主要关注的是文件名生成(通配),因为如果名称包含空格,则整个方法都有缺陷。