一、运行准备
系统环境:Linux操作系统(Centos7)
在执行脚本的主机上安装tcl和expect包,部署expect脚本运行环境
安装tcl
#下载tcl包
wget http://nchc.dl.sourceforge.net/sourceforge/tcl/tcl8.4.11-src.tar.gz
#解压
tar xfvz tcl8.4.11-src.tar.gz
#编译安装
cd tcl8.4.11/unix
./configure --prefix=/usr/tcl --enable-shared
make && make install
#安装完毕以后,进入tcl源代码的根目录,把子目录unix下面的tclUnixPort.h copy到子目录generic中
cp ~/tcl8.4.11/unix/tclUnixPort.h copy ~/tcl8.4.11/generic/
注:暂时不要删除tcl源代码,因为expect的安装过程还需要用。
安装expect
#下载
wget http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz
#解压
tar xzvf expect5.45.tar.gz
#编译安装
cd expect5.45
./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.4.11/generic
make && make install
ln -s /usr/expect/bin/expect /usr/expect/bin/expect
ln -s /usr/expect/bin/expect /usr/bin/expect
此时,在命令行中输入expect应该有如下显示
[root@mongo3 sshTest]# expect
expect1.1>
二、文件说明
| 名称 | 说明 |
|---|---|
| ipAndpasswd.txt | IP及其密码记录文件 |
| sshPassLogin.sh | shell脚本文件 |
| sshPassResult时间戳.txt | 批量主机免密登录结果记录文件,每次运行得到的文件名都不同 |
注:ipAndpasswd.txt中的IP只要是有密码,那么密码必须是正确的,不然脚本运行时会出错

三、脚本说明
利用expect自动化执行ssh-copy-id命令,并与远程终端进行交互。先提取ipAndpasswd.txt中有密码的IP,逐个进行免密登录(将本机公钥发送到远程主机),成功登陆将记录success在sshPassResult时间戳.txt中;在ipAndpasswd.txt中没有密码的IP将会追加在sshPassResult时间戳.txt末尾。
四、运行结果
[root@mongo3 sshTest]#./sshPassLogin.sh
注:如果第一次的时候报错,提示免密登录配置失败,有可能是网络的问题,我在第一次执行脚本时也遇到过了。等待一段时间之后,重新执行一次脚本就好。




注:以下特殊情况同样能正确记录:1.之前做过免密登录,现仍可以免密登录,记录为success;2.之前做过免密登录,现不能免密登录,没有了authorized_keys文件:将重新复制公钥到机器上,并记录为success
五、完整代码
function sshpass(){
local host=$1
local username=$2
local passwd=$3
local ofile=$4
#expect交互脚本,执行ssh-copy-id username@ip的命令
/usr/bin/expect<< EOF
proc sshLogin { host username passwd ofile} {
set file [open $ofile a]
set timeout 60
spawn ssh-copy-id $username@$host
expect {
"yes/no" {send "yes\r"}
"*install the new keys*" {puts \$file "$host success";exp_contin
ue}
"password:" {send "$passwd\r"}
"*already exist*" {
puts \$file "$host success";
}
close $file
}
expect eof
}
sshLogin "$host" "$username" "$passwd" "$ofile"
EOF
}
username=root
ofile="sshPassResult`date +%Y%m%d%H%M%S`.txt"
remoteInfo="ipAndpasswd.txt"
#awk从loginResult.txt提取有密码的IP及其密码信息;用cut切割出IP和密码
awk '{if($2!=null){print $0}}' $remoteInfo | while read LINE
do
host="`echo "$LINE" | cut -d ' ' -f 1`"
passwd="`echo "$LINE" | cut -d ' ' -f 2`"
echo "#####对$host进行ssh免密登录#####"
sshpass $host $username $passwd $ofile
grep -q "$host" $ofile
if [ $? -eq 0 ];then
echo "*****$host success*****"
else
echo "*****$host fail*****"
echo "$host fail" >> $ofile
fi
done
#将没有密码的IP追加到sshResult.txt中
awk '{if($2==null){print $0" nopasswd"}}' $remoteInfo >> $ofile
if [ $? -eq 0 ];then
echo "$ofile save!"
fi
小结
这是我的第一篇简书,表达上还有很多不足的地方,我会继续努力的~如果大家遇到了什么问题,欢迎评论留言呐!
安装步骤参考(转):
https://www.cnblogs.com/daojian/archive/2012/10/10/2718390.html
expect用法参考(转):
https://blog.csdn.net/a9254778/article/details/78636653
https://blog.csdn.net/boyishachang/article/details/8677936