Fork me on GitHub

Expect命令使用详解

通过 Shell 可以实现简单的控制流功能,如:循环、判断等。但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如 ssh 服务器等进行交互的功能。而 Expect 就使用来实现这种功能的工具。

安装expect


1
yum -y install expect

四个关键命令


Expect中最关键的四个命令是send,expect,spawn,interact。

命令 用途
send 用于向进程发送字符串
expect 从进程接收字符串
spawn 启动新的进程
interact 允许用户交互

send命令


send 命令接收一个字符串参数,并将该参数发送到进程
1
2
expect1.1> send "hello world\n"
hello world

expect命令

基础知识

expect命令和send命令正好相反,expect通常是用来等待一个进程的反馈。expect可以接收一个字符串参数,也可以接收正则表达式参数。和上文的send命令结合,现在我们可以看一个最简单的交互式的例子:
1
2
expect "hi\n"
send "hello there!\n"

  • 这两行代码的意思是:从标准输入中等到hi和换行键后,向标准输出输出hello there

比如如下程序:

1
2
3
expect "hi\n"
send "you typed <$expect_out(buffer)>"
send "but I only expected <$expect_out(0,string)>"

当在标准输入中输入

1
2
test
hi

运行结果如下

1
2
3
you typed: test
hi
I only expect: hi

模式-动作

expect最常用的语法是来自tcl语言的模式-动作。这种语法极其灵活,下面我们就各种语法分别说明。

单一分支模式语法:

1
2
expect "hi" {send "You said hi"}
# 匹配到hi后,会输出"you said hi"

多分支模式语法:

1
2
3
expect "hi" { send "You said hi\n" } \
"hello" { send "Hello yourself\n" } \
"bye" { send "That was unexpected\n" }

匹配到hi,hello,bye任意一个字符串时,执行相应的输出。等同于如下写法:

1
2
3
4
5
expect {
"hi" { send "You said hi\n"}
"hello" { send "Hello yourself\n"}
"bye" { send "That was unexpected\n"}
}

spawn命令


上文的所有demo都是和标准输入输出进行交互,但是我们跟希望他可以和某一个进程进行交互。spawm命令就是用来启动新的进程的。spawn后的send和expect命令都是和spawn打开的进程进行交互的。结合上文的send和expect命令我们可以看一下更复杂的程序段了
1
2
3
4
5
6
7
8
9
10
set timeout -1
spawn ftp ftp.test.com //打开新的进程,该进程用户连接远程ftp服务器
expect "Name" //进程返回Name时
send "user\r" //向进程输入anonymous\r
expect "Password:" //进程返回Password:时
send "123456\r" //向进程输入don@libes.com\r
expect "ftp> " //进程返回ftp>时
send "binary\r" //向进程输入binary\r
expect "ftp> " //进程返回ftp>时
send "get test.tar.gz\r" //向进程输入get test.tar.gz\r

这段代码的作用是登录到ftp服务器ftp ftp.test.com上,并以二进制的方式下载服务器上的文件test.tar.gz。程序中有详细的注释

interact命令


到现在为止,我们已经可以结合spawn、expect、send自动化的完成很多任务了。但是,如何让人在适当的时候干预这个过程了。比如下载完ftp文件时,仍然可以停留在ftp命令行状态,以便手动的执行后续命令。interact可以达到这些目的。下面的demo在自动登录ftp后,允许用户交互
1
2
3
4
5
6
spawn ftp ftp.test.com
expect "Name"
send "user\r"
expect "Password:"
send "123456\r"
interact

ssh自动远程登录


如何从机器A上ssh到机器B上,然后执行机器B上的命令?如何使之自动化完成?
1
2
3
4
5
6
7
8
9
#!/usr/bin/expect
spawn ssh root@192.168.16.111
# 用root用户登录到192.168.16.111这台机器
expect "*password:"
send "123\r"
# 当匹配到*password 则输入密码
expect "*#"
interact
# 当匹配到*# 字符是则允许用户交互式输入命令



    本文标题   :   Expect命令使用详解

    文章作者   :   火柴

    发布时间   :   2016年11月29日 - 10时11分

    本文链接   :   http://www.chen-hao.com.cn/Expect命令使用详解.html

    本文字数   :   本文一共有965字

    许可协议   :   Attribution-NonCommercial 4.0

    © 转载请保留以上信息,谢谢合作。