18.3 使用expect实现自动化输入

从字面上就能大概猜出expect的用途,即“期待”系统的输出,且对应地发送输入作为响应。在man文件中是这么介绍expect的:expect是一种能够按照脚本内容设定的方式和交互程序进行“对话”的程序。

由于在Linux中的一些命令不太适合于脚本化的自动运行,比如fdisk、telnet、ftp连接下载等,所以就必须使用expect来解决这些场景下的自动化运行问题。默认情况下系统不会安装expect工具,所以需要先安装再使用,最简单的方法是使用yum安装。

本节将使用expect脚本实现ftp自动登录并下载文件。为演示脚本运行效果,需准备两台虚拟机,按照以下步骤搭建实验环境并运行之。

服务器A:配置为ftp服务器(假设IP为192.168.61.131),如下所示:


#

安装vsftpd

[root@localhost ~]# yum install vsftpd #

安装完成后启动vsftpd

服务

[root@localhost ~]# service vsftpd start Starting vsftpd for vsftpd: [ OK ]

#

varftp

目录中创建TestDownload 文件

[root@localhost ~]# touch varftp/TestDownload


服务器B:创建expect脚本并运行,如下所示。


#

安装expect

[root@localhost ~]# yum install expect #

编辑如下的expect

脚本expect_ftp_auto.exp [root@localhost ~]# cat expect_ftp_auto.exp #!/usr/bin/expect -f set ip [lindex $argv 0 ] #

脚本的第一个参数,远程主机的IP

地址

set file [lindex $argv 1 ] #

脚本的第二个参数,指定下载的文件名

set timeout 10

spawn ftp $ip #

运行ftp $ip

命令

expect "Name*" #

如果出现Name

字符

send "anonymous\r" #

则输入anoymous

并回车

expect "Password:*" #

如果出现Password

字符

send "\r" #

则仅输入回车

expect "ftp>*" #

如果出现ftp>

字符

send "get $file\r" #

则发送get $file

命令

expect {

"Failed" { send_user " Download failed\r";send "quit\r" }

#

如果返回的字符串中含有Failed 则说明下载失败

"send" { send_user " Download ok\r";send "quit\r"}

#

如果返回的字符串中含有send

则说明下载成功

}

expect eof

#

给脚本expect_ftp_auto.exp 加上可执行权限

[root@localhost ~]# chmod +x expect_ftp_auto.exp #

运行脚本,连接192.168.61.131

的ftp

服务器并下载TestDownload 文件

[root@localhost ~]# ./expect_ftp_auto.exp 192.168.61.131 TestDownload spawn ftp 192.168.61.131

Connected to 192.168.61.131.

220 (vsFTPd 2.0.5) 530 Please login with USER and PASS.

530 Please login with USER and PASS.

KERBEROS_V4 rejected as an authentication type Name (192.168.61.131:root): anonymous 331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> get TestDownload local: TestDownload remote: TestDownload 227 Entering Passive Mode (192,168,61,131,181,165) 150 Opening BINARY mode data connection for TestDownload (0 bytes).

226 File send OK.

quitnload ok

ftp> 221 Goodbye.

#

下载一个不存在的文件TestDown ,观察脚本的运行输出

[root@localhost ~]# ./expect_ftp_auto.exp 192.168.61.131 TestDown spawn ftp 192.168.61.131

Connected to 192.168.61.131.

220 (vsFTPd 2.0.5) 530 Please login with USER and PASS.

530 Please login with USER and PASS.

KERBEROS_V4 rejected as an authentication type Name (192.168.61.131:root): anonymous 331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> get TestDown local: TestDown remote: TestDown 227 Entering Passive Mode (192,168,61,131,106,149) 550 Failed to open file.

quitnload failed

ftp> 221 Goodbye.