shell编程 expect自动交互
Posted 我的紫霞辣辣
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell编程 expect自动交互相关的知识,希望对你有一定的参考价值。
expect
expect介绍
expect是一个免费的编程工具,用来实现自动的交互式任务,而无需人为干预。说白了,expect就是一套用来实现自动交互功能的软件。
yum install -y expect
expect基础
在使用expect时,基本上都是和以下四个命令打交道:
命令 | 作用 |
---|---|
spawn | 启动新的进程 |
expect | 从进程接收字符串 |
send | 用于向进程发送字符串 |
interact | 允许用户交互 |
expect实例
[root@m01 ~]# vim expect.sh
#!/usr/bin/expect
# 使用expect来解释该脚本
# spawn是进入expect环境后才可以执行的expect内部命令
# 它主要的功能是给ssh运行进程加个壳,用来传递交互指令
spawn ssh root@192.168.15.7 hostname
expect "yes/no"
send "yes\\n"
# expect "*assword":这里的expect也是expect的一个内部命令,这个命令的意思是判断上次输出结果里是否包含“password”的字符串。
# 如果有则立即返回,否则就等待一段时间后返回,这里等待时长就是前面设置的30秒。
expect "*assword"
send "123\\n" # send 当匹配到对应的输出结果时,就发送密码到打开的ssh进程,执行交互动作
expect eof
===========================================================================================================
[root@m01 ~]# chmod a+x expect.sh
[root@m01 ~]# ./expect.sh
spawn ssh root@192.168.15.7 hostname
The authenticity of host '192.168.15.7 (192.168.15.7)' can't be established.
ECDSA key fingerprint is SHA256:XSO9SAyyHTHXTrPbUhz2Ta0+Jvva07hW38zwJDNWf5o.
ECDSA key fingerprint is MD5:9f:9a:d6:44:ba:0c:41:36:d7:f4:f3:5a:63:9d:38:17.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.15.7' (ECDSA) to the list of known hosts.
root@192.168.15.7's password:
web01
首次登陆之后,再次登陆,就不会出现yes/no的提示了,所以上述脚本再次运行会出现spawn 命令出现交互式提问的expect 匹配不上的情况,此时脚本会阻塞在原地,我们可以set timeout 3设置超时时间,单位为秒,默认情况下是10秒,以保障脚本超时则结束。
[root@m01 ~]# vim expect.sh
#!/usr/bin/expect
spawn ssh root@192.168.15.7 hostname
set timeout 3 # 某一条expect语句在原地匹配,超过了3秒,无论是否匹配成功都会继续执行下一条指令
expect "yes/no"
send "yes\\n"
expect "*assword"
send "123\\n"
expect eof
使用expect命令处理脚本交互信息
[root@m01 ~]# vim expect.sh
#!/usr/bin/expect
spawn ssh root@192.168.15.7 hostname
# 注意
# 1、{}一定要换行
# 2、下述语句就一个expect,代表匹配了一次,会匹配完一行就匹配下一行
expect {
"yes/no" {send "yes\\r";exp_continue}
"*assword" {send "123\\n"}
}
expect eof
===========================================================================================================
[root@m01 ~]# chmod a+x expect.sh
[root@m01 ~]# ./expect.sh
spawn ssh root@192.168.15.7 hostname
root@192.168.15.7's password:
web01
使用expect解释器给脚本传参
shell脚本中的变量无法直接在expect中使用的,若expect需要使用变量,我们需要按照expect解释器的语法自己定义
#!/usr/bin/expect
set timeout -1
set user "root"
set ip "192.168.15.7"
set cmd "hostname"
set pass "123"
spawn ssh $user@$ip $cmd
expect {
"yes/no" {send "yes\\r";exp_continue}
"*assword" {send "$pass\\n"}
}
expect eof
使用bash解释器给脚本传参
- 参考上一个脚本,我们只需要对脚本的一些变量稍加改动,就可以让多个服务器同时执行一条命令。
1. 编写需要操控的服务器信息
cat host1.txt
# root:456:192.168.80.120
# root:456:192.168.80.125
用户名:密码:ip地址
- 编写脚本
vim change2.sh
# !/bin/bash
read -p "请输入你想要批量执行的命令:" cmd # 我们通过cmd = echo svr8 > /etc/hostname来做测试
while read line
do
user=$(echo $line | awk -F: '{print $1}')
passwd=$(echo $line | awk -F: '{print $2}')
ip=$(echo $line | awk -F: '{print $3}')
expect << EOF
spawn ssh $user@$ip $cmd
expect {
"yes/no" {send "yes\\r";exp_continue}
"*assword" {send "$passwd\\n"}
}
expect eof
EOF
done<host1.txt
- 执行脚本
./change2.sh
# 请输入你想要批量执行的命令:echo svr8 > /etc/hostname
# spawn ssh root@192.168.80.120 echo svr8 > /etc/hostname
# root@192.168.80.120's password:
# spawn ssh root@192.168.80.125 echo svr8 > /etc/hostname
# root@192.168.80.125's password:
以上是关于shell编程 expect自动交互的主要内容,如果未能解决你的问题,请参考以下文章