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自动交互的主要内容,如果未能解决你的问题,请参考以下文章

Shell编程之expect免交互

Shell编程之Expect免交互

Shell编程——Expect免交互

无标题文章shell编程之Expect免交互

Shell编程之Expect免交互语句详解

shell进阶——expect免交互工具的使用