expect 实现自动交互脚本
1. 说明
在编写脚本时,可能会遇到需要在另一台主机上执行一个命令,或者在本机拷贝另一台主机内的一个文件。如果两台主机之间没有做互信,就会牵扯到用户输入密码的交互过程,这对编写自动脚本来说, 就行不通了。
要实现在脚本内的自动交互,就需要 expect
2. expect 命令介绍
expect 是一个用来处理交互的命令。借助 expect 可以将交互过程写在一个脚本里,就可以实现自动化完成。上面的问题也能得到解决。
形象来说,如下命令的交互都能得到解决:
- ssh
- scp
- ftp
CentOS / RHEL 安装 expect
# yum install expect -y
2.1 expect 中常用的命令
expect 中最关键的四个命令: send 、 expect 、spawn 、 interact
- send:用于向进程发送字符串
- expect:从进程接收字符串
- spawn:启动新的进程
- interact:允许用户交互
(1) send 命令
send命令接收一个字符串参数,并将该参数发送到进程。
[root@localhost ~]# expect
expect1.1> send "hello china\n"
hello china
(2) expect命令
A. 基础知识
expect命令和send命令正好相反,expect通常是用来等待一个进程的反馈。expect可以接收一个字符串参数,也可以接收正则表达式参数。和上文中的send命令结合。
#!/usr/bin/expect
expect "hi\n"
send "hello there!\n"
上面脚本的意思:
expect "hi\n" --> 从标准输入中等待 "hi\n"
send "hello there!\n" --> 向标准输出输出 hello where
如果写成简单的伪代码如下:
if [ "$cmd" == "hi" ] ; then
echo "hello there!"
fi
来看一个简单的 expect 脚本:
#!/usr/bin/expect
expect "hi\n"
send "you typed <$expect_out(buffer)>"
send "but I only expected <$expect_out(0,string)>"
执行结果:

通过执行脚本,可以判定:
$expect_out(buffer) 匹配到的是所有输入
$expect_out(0,string) 匹配到 expect 参数的输入
B. 模式 - 动作
(a)单一分支模式语法:
expect "hi" {send "You said hi\n"}

只有当输入 hi 时, 才会返回 "You said hi\n"
(b)多分支模式语法:
expect "hi" { send "You said hi\n" } \
"hello" { send "Hello yourself\n" } \
"bye" { send "That was unexpected\n" }

匹配到 hi 、hello 、 bye 执行相应的输出:
hi --> You said hi\n
hello --> You said hi\n
bye --> That was unexpected\n
(3) spawn 命令
上面的测试都是通过手动输入来进行交互的,spawn 命令就是用来启动新的进程,然后通过 send 和 expect 和 spawn 打开的进程进行交互的。
#!/usr/bin/expect
set timeout -1
spawn scp root@192.168.118.15:/root/testfile /root/
expect "*password*"
send "123456\r"
expect "100%"
expect eof
执行结果:

通过 spawn 配合 expect 、send 就能实现自动交互了,接下来分析下这个代码:

(4)interact 命令
通过上面三个命令 spawn 、 send 、 expect 已经能完成很多自动化脚本了,但是,如果需要在适当的时候,需要人工干预这个过程,就需要用到 interact 命令。
#!/usr/bin/expect
set timeout -1
spawn ssh root@192.168.118.15
expect "*password*"
send "123456\r"
expect "#*"
send "ip a | egrep global\r"
interact

3. expect 使用实例
expect 经常是作为脚本出来的, 接下来通过我日常使用的几个实例来说明:
3.1 expect scp的实现
scp 执行流程如图:

在编写实现 scp 之前,我们要考虑:
(1)如果是第一次执行 scp 需要确认服务器公钥,如果不是第一次执行则无需这一步
(2)timeout 时间设定,当拷贝大文件时,timeout设置的过短会造成文件没有完全的传输完成。
在编写脚本的时,需要考虑以上问题,脚本如下:
#!/usr/bin/expect
set timeout 3
set host "192.168.118.15"
set username "root"
set password "123456" # 使用spawn 启动一个新进程执行 scp 命令
spawn scp $username@$host:/root/testfile /root/ # 在这里timeout 为 3秒,超过三秒执行下一个匹配
expect "*yes/no*" {send "yes\r"}
expect "*password*" {send "$password\r"} # 在scp传输文件时,timeout时间设置为无限时,当大文件传输时,需要更多的时间
set timeout -1 # 当匹配到 传输完成 100%后,转到下一步
expect "100%" # 使用 eof 结束该进程,因为上面设置 timeout 为 -1 无限时
expect eof
执行结果:

可以看到,文件传输需要 14 秒,而上面如果设置的超时时间低于 14 秒, 则文件传输不完整。
在日常使用中,expect 结合 shell 使用,在 shell 中引用 expect 脚本如下:
#!/usr/bin/bash
...
[shell 执行脚本]
...
expect <<EOF
set timeout 3
...
[expect 执行脚本]
...
EOF
...
[shell 执行脚本]
...
例如:拷贝一个压缩包到本地,然后解压
#!/bin/bash host="192.168.118.15"
username="root"
password="123456"
expect <<EOF
set timeout 3
spawn scp $username@$host:/root/testfile.tar.gz /root/
expect "*yes/no*" {send "yes\r"}
expect "*password*" {send "$password\r"}
set timeout -1
expect "100%"
expect eof
EOF
echo '开始解压...'
tar xf testfile.tar.gz
if [ $? -eq 0 ]; then
echo '解压完成.'
fi
执行结果:

3.2 expect ssh执行远程命令
ssh远程执行命令流程如下:

执行脚本:
#!/usr/bin/expect
set timeout 3
set host "192.168.118.15"
set username "root"
set password "123456" spawn ssh $username@$host ifconfig
expect "*yes/no*" {send "yes\r"}
expect "*password*" {send "$password\r"}
expect eof
执行结果:

expect 匹配 shell 使用还是很强大的,尤其是在没有 python 和无法连接互联网的环境中。
expect 实现自动交互脚本的更多相关文章
- expect实现自动交互由浅入深
expect实现自动交互由浅入深 作为运维人员可以通过Shell可以实现简单的控制流功能,如:循环.判断等.但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet ...
- 自动交互脚本之expect使用记录
之前一直没怎么用这个命令,意外用了一下,还不错,那这个是干嘛的呢 我们或多或少会远程登录其他服务器,需要执行某项任务,通常需要手动接入,输入密码啊,等等 那我们如何有效的自动执行呢,expect可以解 ...
- 使用expect实现自动交互,shell命令行自动输入,脚本自动化,变量引用,expect spawn执行带引号命令,expect 变量为空,不生效,不能匹配通配符*,函数,数组
背景 有需求,在允许命令或者脚本跳出交互行,需要进行内容输入,但需要人手动输入,不是很方便,此时可以通过expect来实现自动互动交互. expect是一个自动交互功能的工具,可以满足代替我们实际工作 ...
- 用expect做自动应答脚本
Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools).使用它系统管理员可以创 ...
- 使用expect实现自动交互,shell命令行自动输入
背景 有需求,在允许命令或者脚本跳出交互行,需要进行内容输入,但需要人手动输入,不是很方便,此时可以通过expect来实现自动互动交互. expect是一个自动交互功能的工具,可以满足代替我们实际工作 ...
- Linux Expect自动交互脚本
https://likegeeks.com/expect-command/ In the previous post, we talked about writing practical shell ...
- Linux--使用expect进行自动交互
在linux下进行一些操作时,有时需要与机器进行一些交互操作,比如切换账号时输入账号密码,传输文件时输入账号密码登陆远程机器等,但有时候这些动作需要在shell脚本中进行,这个时候就可以使用expec ...
- 用expect做自动运行脚本
下面的脚本演示了在Ubuntu上安装expect,写一个切换用户的expect脚本,并运行脚本看到效果的过程. root@guserver:~# apt-get install expect godu ...
- expect简单自动交互-用于密码、命令输入
1. 安装expect #yum -y install expect 2. 新建.exp文件,用于ssh交换机 #vi exp.exp #!/bin/expect set f [open ipfile ...
随机推荐
- kth-largest-element
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- 【CSP-S 2019】【洛谷P5665】划分【单调队列dp】
前言 \(csp\)时发现自己做过类似这道题的题目 : P4954 [USACO09Open] Tower of Hay 干草塔 然后回忆了差不多\(15min\)才想出来... 然后就敲了\(88p ...
- hello world 程序的生成过程
一个c / c ++文件需要经过预先(预处理),编译(编译),编译(汇编)和链接(链接)等四步,才能生成可执行程序. 在日常编译中,通常“编译”统称这四步: gcc -c xxx .s:汇编 gcc ...
- django 第三天 视图
今日内容 一.url路由分发之include 项目文件夹下的urls.py文件中的url写法: from django.conf.urls import url,include from django ...
- VS - ActionFilterAttribute
Global.asax.cs public class MvcApplication : System.Web.HttpApplication { public static void Registe ...
- mysql 时区更改;5.7 弱口令
一.mysql 更改表名称: show databases; use 库名; show tables; rename table 旧表名 to 新表名: 示例: rename table old to ...
- RookeyFrame Bug 线上创建的DLL被删除了 模块无法删除 临时解决
不知道什么情况 在线创建模块,DLL被删除了,但是模块的相关数据无法删除.可以按照下面的方法临时用一下. 产生这个的原因,好像是Config里面的NeedInit一直都是true,没有改为false, ...
- matlab 万能实用的非线性曲线拟合方法
——转载网络 在科学计算和工程应用中,经常会遇到需要拟合一系列的离散数据,最近找了很多相关的文章方法,在这里进行总结一下其中最完整.几乎能解决所有离散参数非线性拟合的方法 第一步:得到散点数据 根据你 ...
- CStatic 控件设置文本,不能重回问题
CStatic m_page_text_; m_page_text_.SetWindowText(str); CRect rt; m_page_text_.GetWindowRect(&rt) ...
- Windows下基于IIS服务的SSL服务器的配置
Windows下基于IIS服务的SSL服务器的配置 实验环境 Windows Server 2008 R1(CA) Windows Server 2008 R2(web服务器) Windows 7 x ...