Expect使用小记

By francis_hao    May 31,2017

本文翻译了部分Expect的man手册,只选取了个人常用的功能,因此并不完善。

Expect是一个可以和交互式程序对话的程序

概述

介绍

通过脚本,Expect可以知道应该从对话程序中期望得到什么,和应该回应什么。它支持多分支结构,并且用户可以在需要的时候取得控制权,并在之后将控制权交还给脚本。

Expect也可以被直接用在c或c++中,详见libexpect(3)。

Expect可以做的事情:telnet、ftp、ssh和scp等等(如果不在意用户名和密码信息)

用法

Expect从cmdfile(-f选项指定)中读取一系列的命令去执行。但一般更常用的方式是将文件作为可执行脚本,在文件第一行添加如下类似的标识,以告知shell通过Expect解析本文件。

#!/usr/bin/expect


选项


说明


-c


可执行命令的前置符,其后的命令应该被引起来,该选项可以使用多次,每个-c可以跟多个以分号分隔的命令。命令按照出现的顺序执行,例如:

expect -c "puts first\n; puts second" -c "puts three"


-d


输出一些诊断信息,命令执行时的内部动作。当你写的脚本和预期不符时,可用此项来调试脚本


-D


交互式的调试器,类似gdb。适合专业人士使用


-f


指定Expect读取的文件,如果文件是-,则表示是从标准输入读取。该选项会将文件一次性全部读入内存,该选项是可选的


-b


类似-f选项,只是每次只读取一行


-i


以交互的方式运行expect,等效直接敲expect


--


可以用来界定选项的结束,此项可以用在当你想传递一个类似选项的参数时,防止Expect误认为是选项


-N/-n


如果$exp_library/expect.rc和~/.expect.rc存在,Expect会分别自动读取,若要阻止此过程则需要分别指定-N和-n。此项一般用不上。


-v


输出版本号并退出

可选项args的内容以列表的形式被保存在argv中,argc被初始化为argv的长度(个数),argv0保存脚本的名字。

命令

Expect使用Tcl的语法,又进行了一些扩展,比如spawn、send、expect和interact等。常用的扩展命令如下,按常用度排序

最好的介绍Expect和Tcl的资料是《Exploring Expect》这本书。本man手册虽然包含示例但十分有限,毕竟man手册主要作为参考资料。

在本文中Expect指Expect程序,expect指Expect程序中的expect命令。

spawn

spawn [args] program [args]

创建一个新的进程运行program [args]。program的标准输入、标准输出和标准错误都连接到Expect,这样程序就可以被Expect读写了。当Expect执行close命令或者进程关闭了任何文件标识符时,连接会断开。

当以spawn启动一个进程时,进程描述符被赋给变量spawn_id,它表示了当前进程,spawn_id可被读写,以实现任务控制。

正常情况下,spawn只花费很少的时间,如果spawn耗费了大量的时间,可能是由于pty的问题,此时可以通过-d选项显示执行过程。


选项


说明


-noecho


默认情况下,spawn会回显命令名和参数。此选项可以取消回显。


-ignore


指定在spawned process种要忽略的信号。

expect

expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]

等待,直到模式patn匹配到spawn打开的进程的输出,超过指定的时间,或遇到EOF。

如果模式关键字是eof,那么对应的执行体是处理遇到文件结尾的

如果模式关键字是timeout,那么对应的执行体是处理超时的,如果没有指明timeout,则默认不会做任何动作。默认的超时时间是10秒,但是可以通过如下命令重设

set timeout 30

如果设置为-1,则意味着无限等待。

如果模式关键字是default,那么对应的执行体会处理超时或文件结尾。

每次新的输出到达时,会按顺序比较每个模式,如果模式匹配到了,那么对应的执行体会被执行。如果有多个模式匹配,只执行第一个出现的。

下面的例子,看起来像一个可以成功登陆的脚本片段。


expect {
    "yes/no"        {send "yes\r";exp_continue}
    "password:"    {send "$passwd\r"}
    default        {exit}
}

字串中可以使用^匹配起始串,用$匹配结尾串。

如果模式关键词是null,那么仅当匹配到一个单个ascii字符"0"时才会执行后面的执行体。没有可用的办法来匹配0字节数据,不论是通过全匹配还是正则匹配。

在获得匹配后,程序的所有输出字串,截至匹配字串,被保存在变量expect_out(buffer)中,多至九个匹配子串分别被保存在变量expect_out(1,string)至expect_out(9,string)中。


选项


说明


-gl


保护以"-"开始的模式不被认为是选项


-re


正则表达式,在单项前面指定


-ex


匹配确切的字串,不对*、^和$等特殊字符进行翻译


-nocase


不区分大小写


-timeout


设置当前expect的超时时间,而不是使用变量timeout的时间

exp_continue

exp_continue [-continue_timer]

允许expect继续执行自身而不是往下执行,默认情况下,exp_continue会重置timeout,如果不想重置timeout,使用-continue_timer选项。

expect_user

expect_user [expect_args]

类似expect,不过是从标准输入读取字符,行必须以回车结尾,以使expect能识别它们。

send

send [-flags] string

发送string到当前进程,例如:

send "hello world\r"

就是发送h e l l o <blank> w o r l d <return>到当前进程,

字符会立即被发送,尽管那些行缓冲的程序只会在有回车键时才读取,回车键用‘\r‘表示。因此,下面的示例和上面示例等同。

send "hello "
send "world\r"


选项


说明


--


其后的参数被强制解释成字串,而不是选项。


-i


选项说明字串发送给spawn_id。


-s\-h


慢的输入\类人的输入方式,可以提供输入的间隔设置。具体参见man手册

   

send_error

send_error [-flags] string

类似send,不过输出发送到标准错误,而不是当前进程

send_log

send_log [--] string

类似send,不过string只发送到log文件。(see log_file)

send_tty

send_tty [-flags] string

类似send,不过输出发送到/dev/tty而不是当前进程。

send_user

send_user [-flags] string

类似send,不过输出发送到标准输出,而不是当前进程。

interact

interact [string1 body1] ... [stringn [bodyn]]

将当前进程的控制权交付给用户。

string-body对可以作为参数,以使当有string输入时,执行body。下面的示例看上去是一个可运行片段。


interact {
    "abc" {send_user "you typed abc\n"}
    "123" {send_user "you typed 123\n"}
}

输入的字符会按string列出的顺序进行匹配,当有部分匹配时,当前输入的字符不会被发送到当前进程,只有当后续输入的字符不能使之匹配时才会发送,若匹配则执行body。以上例为例,在输入"abc"的过程中,进程不会回显这些字符,如果输入"abq",则只有在输入到"q"时,"abq"才会同时被回显。


选项


说明


-ex


防止以"-"开头的模式被翻译成选项


-re


用正则匹配的模式翻译string,此选项下匹配的子串被保存在变量interact_out中。类似expect的expect_out。


-echo


回显每一个字符,即使这个字符会被匹配中

   

当模式是eof时,表示遇到文件结尾的行为,默认是"return"。

当模式是timeout时(需指定超时时间),表示在指定时间没有输入时的行为,此项没有默认的超时时间,变量timeout的值在此无效。

当模式是null时,仅当匹配到一个单个ascii字符"0"时才会执行后面的执行体。没有可用的办法来匹配0字节数据,不论是通过全匹配和正则匹配。

interact中的return使interact返回到它的调用。而inter_return使interact的调用执行return

sleep

sleep seconds

脚本进入睡眠模式,睡眠时间单位为秒

close

close [-slave] [-onexec 0|1] [-i spawn_id]

关闭连接到当前进程的连接


选项


说明


-i


指定关闭名为spawn_id的进程


-onexec


检测是否有新打开的进程或进程是否有重叠,若有,

0:保持打开,1:强制关闭


-slave


关闭spawn_id关联的子进程

exit

Expec退出


本文由 刘英皓 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:
转载自:http://www.cnblogs.com/yinghao1991/p/6926125.html

参考

【1】man expect

时间: 2024-10-09 22:19:42

Expect使用小记的相关文章

expect spawn、linux expect 用法小记

使用expect实现自动登录的脚本,网上有很多,可是都没有一个明白的说明,初学者一般都是照抄.收藏.可是为什么要这么写却不知其然.本文用一个最短的例子说明脚本的原理. 脚本代码如下: 1 #!/usr/bin/expect 2 set timeout 30 3 spawn ssh -l username 192.168.1.1 4 expect "password:" 5 send "ispass\r" 6 interact 1. [#!/usr/bin/expec

【转】shell expect spawn、linux expect 用法小记 看着舒服点

使用expect实现自动登录的脚本,网上有很多,可是都没有一个明白的说明,初学者一般都是照抄.收藏.可是为什么要这么写却不知其然.本文用一个最短的例子说明脚本的原理. 脚本代码如下: ############################################## #!/usr/bin/expect set timeout 30 spawn ssh -l username 192.168.1.1 expect "password:" send "ispass\r&

Linux - 通过expect工具实现脚本的自动交互

目录 1 安装expect工具 2 expect的常用命令 3 作用原理简介 3.1 示例脚本 3.2 脚本功能解读 4 其他脚本使用示例 4.1 直接通过expect执行多条命令 4.2 通过shell调用expect执行多条命令 5 spawn not found 的解决 1 安装expect工具 expect是建立在tcl基础上的一个自动化交互套件, 在一些需要交互输入指令的场景下, 可通过脚本设置自动进行交互通信. 其交互流程是: spawn启动指定进程 -> expect获取指定关键字

shell脚本交互:expect学习笔记及实例详解

最近项目需求,需要写一些shell脚本交互,管道不够用时,expect可以很好的实现脚本之间交互,搜索资料,发现网上好多文章都是转载的,觉得这篇文章还不错,所以简单修改之后拿过来和大家分享一下~ 1. expect是spawn: 后面加上需要执行的shell命令,比如说spawn sudo touch testfile 1.3 expect: 只有spawn执行的命令结果才会被expect捕捉到,因为spawn会启动一个进程,只有这个进程的相关信息才会被捕捉到,主要包括:标准输入的提示信息,Li

SpringBoot - 二零一七0421小记

一.SpringBoot使用起来比起SpringMVC更便捷,在注解上的小变化,我记录了下面几个: @Controller + @ResponseBody = SpringMVC中用@RestController来代替前面两个注解,通过这个注解,可以将所有的前端http请求放入SpringBoot的Controller容器中,并返回json格式的数据给前端 @RequestMapping(value={"/hello","/hi"},method=RequestMe

expect使用

有些命令却需要用户手动去就交互如passwd.scp 对自动部署免去用户交互很痛苦,expect能很好的解决这类问题. expect的核心是spawn expect send set spawn 调用要执行的命令 expect 等待命令提示信息的出现,也就是捕捉用户输入的提示: send 发送需要交互的值,替代了用户手动输入内容 set 设置变量值 interact 执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了.如果没有这一句登录完成后会退出,而不是留在远程终端上. ex

expect 使用实例

shell脚本实现ssh自动登录远程服务器示例: #!/usr/bin/expect spawn ssh [email protected] expect "*password:" send "123\r" expect "*#"interact Expect是一个用来处理交互的命令.借助Expect,我们可以将交互过程写在一个脚本上,使之自动化完成.形象的说,ssh登录,ftp登录等都符合交互的定义.下文我们首先提出一个问题,然后介绍基础知四个

centos 7 expect + shell实现批量创建文件

这个问题好久了,一直没整理出来.记得还是上次面试的时候问到如何批量修改1000台机器的主机名.这里给出批量创建内容为Hello,名为1.txt的文件. 一.首先安装expect yum install -y expect 二.准备工作:(1)准备IP地址的列表.vim ip.txt 192.168.1.88 192.168.1.89 192.168.1.90 (2)准备要执行的命令.vim cmd.txt mkdir /tmp/test 三.脚本部分 #!/bin/bash passwd="12

bash嵌套expect实现交换机的交互式登录实例

1. expect实现参数传递 1.1 实现 $argv 参数数组 expect脚本可以接受从bash传递过来的参数. 可以使用[lindex $argv n]获得,n从0开始,分别表示第一个,第二个,第三个....参数 1.2 样例 cat telnet.exp #!/usr/bin/expect set host [lindex $argv 0] set passwd [lindex $argv 1] set passwden [lindex $argv 2] spawn telnet $h