#!/bin/bash
#检测是否安装expect
rpm -q expect &> /dev/null
if [ $? -ne 0 ] #-ne是不等于,没有expect就安装
then
yum install -y expect
fi
#生成公钥
if [ ! -f /root/.ssh/id_rsa ] # !是非或不是。如果没有私钥就生成一个
then
ssh-keygen -P "" -f ~/.ssh/id_rsa #ssh-keygen -p 命令用于更改现有SSH密钥对的密码
#-f 是问私钥位置在哪里。
fi
#创建一个IP地址文件
>ip.txt
#使用for循环ping测试主机是否在线
for i in {2..254}
do {
ip=192.168.110.$i
ping -c1 -W1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo "$ip" >> ip.txt
/usr/bin/expect <<-EOF #-EOF的-表示能识别tab,也可以不加
set timeout 10 #等待10s
spawn ssh-copy-id $ip #使用命令
expect{
"yes/no" {send "yes\r";exp_continue} #交互过程中遇到yes/no的语句,输入yes回车\r是回车。exp_continue是立即结束该命令。
"password:" {send "这里输入密码\r"}
}
expect eof #用于等待与之交互的进程结束。
EOF
fi
}&
wait #等待 使用{ }&表示高并发等待结束。
done
echo "公钥传输成功"
-
检查与安装
expect
: 脚本首先检查系统中是否已安装expect
,未安装则通过yum
命令自动安装,这是很好的实践,确保了后续expect
命令能够顺利执行。 -
生成SSH密钥对: 如果
/root/.ssh/id_rsa
不存在,脚本会自动生成一个无密码的SSH密钥对。注意,生产环境中通常不推荐无密码的密钥对,因为这可能会降低安全性。但若是在受控或测试环境中,为了方便自动化操作,这是可行的。 -
创建IP地址文件: 通过重定向空输出到
ip.txt
清空或创建文件,用于记录在线主机的IP地址。 -
并发执行ping与密钥分发: 使用
for
循环结合并行处理({ }&
和wait
)提高了效率,同时利用expect
来自动化处理SSH首次登录时的密码输入和确认提示。这种做法在大量主机上部署时非常高效。