Shell编程之Expect免交互

Shell编程之Expect免交互

Expect概述

Expect安装

Expect基本命令

Expect执行方式

Expect案例

Expect概述

Expect

  • Expect是建立在tcl基础上的一个工具,Expect 是用来进行自动化控制和测试的工具。主要解决shell脚本中不可交互的问题。对于大规模的linux运维很有帮助
  • linux运维和开发中,我们经常需要远程登录服务器进行操作,登录的过程是一个交互的过程,可能会需要输入yes/no password等信息。为了模拟这种输入,可以使用Expect脚本

Expect安装

挂载光盘

制作本地YUM源

执行安装命令

  • yum install expect -y
[root@localhost ~]# yum install expect -y
已加载插件:fastestmirror, langpacks
base                                                            | 3.6 kB  00:00:00     
extras                                                          | 2.9 kB  00:00:00     
updates                                                         | 2.9 kB  00:00:00     
(1/4): extras/7/x86_64/primary_db                               | 152 kB  00:00:00     
(2/4): base/7/x86_64/group_gz                                   | 165 kB  00:00:00     
(3/4): updates/7/x86_64/primary_db                              | 1.9 MB  00:00:01     
...//省略部分内容...
  正在安装    : 1:tcl-8.5.13-8.el7.x86_64                                          1/2 
  正在安装    : expect-5.45-14.el7_1.x86_64                                        2/2 
  验证中      : 1:tcl-8.5.13-8.el7.x86_64                                          1/2 
  验证中      : expect-5.45-14.el7_1.x86_64                                        2/2 

已安装:
  expect.x86_64 0:5.45-14.el7_1                                                        

作为依赖被安装:
  tcl.x86_64 1:8.5.13-8.el7                                                            

完毕!

Expect基本命令

send:向进程发送字符串,用于模拟用户的输入

  • 该命令不能自动回车换行,一般要加\r(回车)

expect

  • expect的一个内部命令,判断上次输出结果里是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回。
  • 只能捕捉由spawn启动的进程的输出

spawn:启动进程,并跟踪后续交互信息

interact:执行完成后保持交互状态,把控制权交给控制台

Timeout:指定超时时间,过期则继续执行后续指令

  • 单位是:秒
  • timeout -1为永不超时
  • 默认情况下,timeout10

exp_ continue

  • 允许expect继续向下执行指令

send_ user

  • 回显命令,相当于echo

$argv参数数组

  • Expect脚本可以接受从bash传递的参数.可以使用[lindex $argv n]获得,n0开始,分别表示第一个,第二个,第三个…参数

Expect脚本必须以interact或expect eof结束,执行自动化任务通常expect eof就够了

  • expect eof是在等待结束标志。由spawn启动的命令 在结束时会产生一个eof标记,expect eof御在等待这个标记

Expect语法

单一分支语法

expect "password:" {send "mypassword\r";}

多分支模式语法

expect "aaa" {send"AAA\r"}   //send命令不具备回车换行功能,一般要加\r或\n
expect "aaa" {send"AAA\r"}
expect "aaa" {send"AAA\r"}
expect {
    "aaa" {send "AAA\r"}    //只要配置aaa或bbb或ccc中的任何一个,执行相应的send语句后退出该expect语句
    "bbb" {send "BBB\r"}
    "ccc" {send "CCC\r"}
}
expect {
    "aaa" {send "AAA";exp_continue}       //exp_continue表示继续后面的匹配,如果匹配了aaa,执行
    "bbb" {send "BBB";exp_continue}         完send语句后还要继续向下匹配bbb
    "ccc" {send "CCC"}
}

Expect执行方式

直接执行

  • 使用expect免交互使用ssh远程登录另一台服务器,这里我开启两台Linux服务器。

[root@localhost ~]# vim demo19.sh     //编辑脚本文件
#!/usr/bin/expect                     //expect二进制文件路径
set timeout 5                         //超时时间
log_file tast.log                     //记录日志文件存放位置
log_user 1                            //一个用户
set hostname [lindex $argv 0]         //设定第一个位置参数传递并设置变量名hostname
set password [lindex $argv 1]         //设定第二个位置参数传递并设置变量名password
spawn ssh root@$hostname              //追踪命令
expect {                              //使用expect命令捕捉条件,设定输入信息,进行免交互设置
        "(yes/no)"                    //设定匹配条件
        {send "yes\r";exp_continue}   //条件匹配并输入内容,并继续向下匹配
        "*password"                   //设定匹配条件
        {send "$password\r"}          //条件匹配,引用位置变量输入信息
}
interact                               //完成后将控制权交给控制台
[root@localhost ~]# chmod +x demo19.sh  //给脚本文件添加执行权限
[root@localhost ~]# ./demo19.sh 192.168.144.135 123123    //执行脚本
spawn ssh root@192.168.144.135
The authenticity of host '192.168.144.135 (192.168.144.135)' can't be established.
ECDSA key fingerprint is SHA256:B8IsZOFG7FbtVkIK+dMILmo0iA4OEIeVGY0GnnCbXhk.
ECDSA key fingerprint is MD5:c2:d8:09:17:de:6e:ec:07:06:1b:ac:b6:1e:bd:62:09.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.144.135' (ECDSA) to the list of known hosts.
root@192.168.144.135's password: 
Last login: Sun Oct 13 23:29:38 2019 from 192.168.144.1     //自动登录服务器
[root@localhost ~]# ifconfig                           //查看服务器IP地址
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.144.135  netmask 255.255.255.0  broadcast 192.168.144.255    //成功登录
        inet6 fe80::a85a:c203:e2e:3f3c  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::ad78:663f:1f02:22e4  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:75:9f:c8  txqueuelen 1000  (Ethernet)
        ...//省略部分内容...

嵌入执行

[root@localhost ~]# vim demo20.sh     //编辑脚本文件
#!/bin/bash                           
hostname=$1                            //设置位置参数变量
password=$2
/usr/bin/expect <<-EOF          //加载expect功能,EOF前面加“-”是为增加容错性,-EOF 前面的“-"只能容错制表
spawn ssh root@$hostname          符,不能容错空格
expect {
        "(yes/no)"
        {send "yes\r";exp_continue}       //进行免交互配置
        "*password"
        {send "$password\r"}
}
expect "*]#"                              //捕捉内容结尾为“]#”的内容
send "exit\r"                             //匹配后输入exit退出登录
expect eof                                //等待结束标志
EOF                                       //结束标志
[root@localhost ~]# chmod +x demo20.sh    //添加执行权限
[root@localhost ~]# ./demo20.sh 192.168.144.135 123123    //执行脚本,并输入位置变量
spawn ssh root@192.168.144.135
root@192.168.144.135's password: 
Last login: Sun Oct 13 23:58:05 2019 from 192.168.144.1
[root@localhost ~]# exit
登出
Connection to 192.168.144.135 closed.
[root@localhost ~]# ifconfig                       //查看IP地址信息
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.144.133  netmask 255.255.255.0  broadcast 192.168.144.255
        inet6 fe80::a85a:c203:e2e:3f3c  prefixlen 64  scopeid 0x20<link>   //成功登出
        ether 00:0c:29:5b:d3:a0  txqueuelen 1000  (Ethernet)
        RX packets 11058  bytes 855440 (835.3 KiB)
        ...//省略部分内容...
    原文作者:SiceLc
    原文地址: https://blog.51cto.com/14473285/2442145
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞