expect介绍
expect是一个自动交互功能的工具,可以满足代替我们实际工作中需要从终端手动输入某些内容来使得程序或命令继续运行的目的。如安装软件是时的一些提示,ssh远程主机执行命令时需要多次输入密码的情况
expect主要命令
spawn 启动新进程,用于执行shell命令
send 发送字符串给expect控制的进程
set 设置变量 set user root
expect 从发起交互的命令的进程接受字符串,用于匹配我们预想的字符串
exp_continue 继续执行接下来的交互操作
set timeout -1 设置超时时间 永远等待
set timeout 10 设置超时时间 10秒
interact 将脚本的控制权交给用户,用户继续使用shell执行命令
$argv expect 脚本可以接受从bash传递过来的参数
安装expect
yum install expect
免密码通过SSH登录服务器
[root@linux /]# vim ssh.exp
#!/usr/bin/expect
set ip "172.16.0.8"
set user "root"
set pwd "123456"
spawn ssh $user@$ip
expect {
"yes/no" { send "yes\r"; exp_continue } #exp_continue 未出现时继续往下执行
"password" { send "$pwd\r" } # \r 是回车的意思
}
interact
[root@linux /]# expect ssh.exp
spawn ssh root@172.16.0.8
root@172.16.0.8's password:
Last login: Thu Aug 6 13:51:42 2020 from www.www.www
[root@nginx1 ~]# ifconfig ens33|sed -n '2p'|awk '{print $2}'
172.16.0.8
[root@nginx1 ~]# exit
登出
Connection to 172.16.0.8 closed.
[root@linux /]#
批量获取在线的IP地址机进行批量秘钥分发
[root@linux /]# vim ssh.sh
#!/bin/bash
>ip.txt
#判断公钥是否生成
if [ ! -f ~/.ssh/id_rsa ]
then
ssh-keygen -P "" -f ~/.ssh/id_rsa
fi
#获取在线的主机
for i in {3..20}
do
ping -c1 -w1 172.16.0.$i &>/dev/null
if [ $? -eq 0 ];then
echo 172.16.0.$i >>ip.txt
fi
done
#批量分发秘钥
pass=123456
while read line
do
/usr/bin/expect<<EOF
set timeout 2
spawn ssh-copy-id root@$line
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "$pass\r" };
}
expect eof
EOF
done<ip.txt
[root@linux /]# sh ssh.sh
spawn ssh-copy-id root@172.16.0.4
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.16.0.4's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@172.16.0.4'"
and check to make sure that only the key(s) you wanted were added.
spawn ssh-copy-id root@172.16.0.5
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.16.0.5's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@172.16.0.5'"
and check to make sure that only the key(s) you wanted were added.
spawn ssh-copy-id root@172.16.0.8
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.16.0.8's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@172.16.0.8'"
and check to make sure that only the key(s) you wanted were added.
spawn ssh-copy-id root@172.16.0.10
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.16.0.10's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@172.16.0.10'"
and check to make sure that only the key(s) you wanted were added.
测试结果
[root@linux /]# ssh root@172.16.0.4
Last login: Thu Aug 6 16:16:01 2020 from master
[root@linux ~]# ifconfig ens33|sed -n '2p'|awk '{print $2}'
172.16.0.4
[root@linux ~]# exit
登出
Connection to 172.16.0.4 closed.
[root@linux /]# ssh root@172.16.0.5
Last login: Thu Aug 6 14:33:17 2020 from master
[root@linux ~]# ifconfig ens33|sed -n '2p'|awk '{print $2}'
172.16.0.5
[root@linux ~]# exit
登出
Connection to 172.16.0.5 closed.
[root@linux /]# ssh root@172.16.0.8
Last login: Thu Aug 6 13:56:41 2020 from www.www.www
[root@nginx1 ~]# ifconfig ens33|sed -n '2p'|awk '{print $2}'
172.16.0.8
[root@nginx1 ~]# exit
登出
Connection to 172.16.0.8 closed.