Shell脚本和expect实现自动交互

时间:2022-07-24
本文章向大家介绍Shell脚本和expect实现自动交互,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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 "yesr"; exp_continue }  #exp_continue 未出现时继续往下执行
"password" { send "$pwdr" }   # 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 "yesr"; exp_continue }
  "password:" { send "$passr" };
}
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.