使用 EXPECT 自动化任务

作者:Vinnie Saladino

作为 18 台 VAX 和 6 台 HP/UNIX 机器的系统管理员,我一直在寻找更轻松的做事方式。我一直做的一件事是为 UNIX 编写 shell 脚本,为 VMS 编写命令程序,以自动化我的某些任务。如果我可以从一台计算机运行它们,我就可以在一个地方管理整个世界,而无需登录到每台计算机来运行我必须执行的每个任务。

我最初尝试使用 VAX/VMS 命令文件来 TELNET 到其他机器。但该方法很快就被放弃了,因为远程计算机的 I/O 响应先于我的命令文件执行输入语句。登录很快就挂起了。然后我尝试从 UNIX 脚本中 TELNET,同样的事情发生了。这种挫败感就是为什么管理员的工作很艰难的原因。

在 Barnes & Noble 书店闲逛,靠在 UNIX 书架上总是一种不错的消遣——你看上去很酷,而且还能帮助书本除尘。我就是这样发现《Exploring EXPECT》这本书的,书名很有趣,封底写着“自动化 TELNET、FTP、passwd...”。我买了这本书——是的,我有时会以貌取书。

Don Libes 撰写的优秀书籍《Exploring EXPECT》(由 O'Reilly & Associates 出版)包含了关于控制任何派生进程的所有必要知识。您可以派生一个游戏并与之交互,就像远程 TELNET 会话一样容易。这本书相当长且非常详细,但不要被吓倒。有一种简单的方法可以学习编写 EXPECT 脚本;我稍后会讲到。

长话短说,EXPECT 是一个用于自动化交互式程序的工具包,例如 TELNET 和 FTP,由 Don Libes 编写。EXPECT 必须是历史上系统管理员最伟大的资产。最后,我可以轻松地编写和执行 TELNET 登录脚本,并使用一台机器上的脚本文件执行任何我想做的事情。

EXPECT 从脚本文件中读取命令,派生一个像 TELNET 这样的进程,将文本从脚本文件发送到 TELNET 进程,保存从 TELNET 会话返回的每个字符,并“查找”用户“期望”的已知字符串。脚本可以测试不同的字符串,并根据结果执行不同的代码。TELNET 脚本可以内置很多智能。

买书后上班的第一天,我登录到我的一台 HP/UNIX 机器,执行了 man expect 命令,并收到消息“未找到条目”。在尝试了几次之后,我给 HP 打了电话。EXPECT 和 Tcl(EXPECT 基于的语言)未安装,甚至 HP 的 CD-ROM 发行介质中也没有提供。HP 建议我从网站下载 Tcl 和 EXPECT 并安装它们。我不喜欢在生产服务器上进行这种操作。在说了几句我最喜欢的脏话之后,我去了我的桌面 Linux 系统。

当我安装 Linux 时,我划分了一个 1GB 的分区,进行了完整的 Linux 安装,并与 MS Windows 双启动。两分钟重启后,Linux 就启动并运行了。我再次运行了 man expect。这次,我得到了一个 man 页面——一个非常长且信息丰富的 man 页面。

“Introduction EXPECT”是一个根据脚本“与”其他交互式程序“对话”的程序。这是否意味着我已经拥有它了?我运行了命令

find / -name expect

并得到了这个结果

/var/lib/LST/installed/expect
/var/lib/LST/contents/expect
/usr/bin/expect
哦耶,我有了——我爱 Linux!

在使用命令 ll | more 浏览 /usr/bin 时,我找到了 autoexpect。什么是 autoexpect?书里没有提到它,所以我输入了 man autoexpect 并收到了以下输出

autoexpect - generate an EXPECT script from watching a session.

这是一个很酷的程序。我可以从 Linux 运行到 VAX 的 TELNET 或 FTP 会话,并从该会话创建一个 EXPECT 脚本,我可以随时运行它。

没有什么比实际操作更好了。我使用 FTP 登录到 VAX,put 了一个文件并退出了。我将 EXPECT 的 man 页面复制到一个文件,然后使用 FTP 将其放到 VAX 上。

man expect | col -b > man_expect.txt

接下来,我使用 FTP 连接到名为 ZEUS 的 VAX,并将文件 man_expect.txt 放到该机器上。

autoexpect -f test1.exp FTP ZEUS
autoexpect started, file is test1.exp
connected to ZEUS
220 Zeus FTP Server
Name (zeus:vinnie): v12321
Password:
230 User logged in.
Remote system type is VMS.
FTP> put man_expect.txt
 ...
FTP> quit
221 Goodbye.
Autoexpect done, file is test1.exp
文件 test1.exp 是由 autoexpect 创建的脚本。我可以随时重新运行此脚本,只需在提示符下键入 test1.exp 即可。检查 test1.exp 显示了 Linux 机器和 VAX 之间双向对话的详细信息。每个字符都保存在 sendexpect 命令中。甚至密码也会被保存,因此必须小心这些脚本。

我编辑了我的 test1.exp 脚本以删除注释。我还删除了所有非必要的 expect 命令,只留下最基本的内容。脚本简洁明了。EXPECT 的整个概念非常简单——像正常键入一样发送命令,例如 VAX FTP 提示符

expect -exact "FTP> "

TELNET 也很容易,但是 autoexpect 创建的脚本无法运行。为什么?让两台计算机相互通信的基本问题是它们永远不会说完全相同的话两次;特别是,时间和日期字符串总是变化的。Don 在 EXPECT 的 man 页面和他的书中都指出了这一点。

当我使用 TELNET 登录到我的 VAX 时,在“Welcome”消息之后,它返回给我的第一件事是时间和日期。在我执行“Directory Listing”之后,返回了文件名和文件总数。这些响应随时间而变化。从 autoexpect 脚本中删除它们会导致它们每次都能完美地重新运行。我写这篇文章是为了介绍 EXPECT,并展示它有多么容易使用。《Exploring EXPECT》详细介绍了 EXPECT 的各个方面——从它的工作原理,到在 EXPECT 中编程双向对话,以及如何将选定的 EXPECT 输出记录到文件中。许多您从未想过可以自动化的事情都可以在您坐下来享受阅读Linux Journal 的同时运行。

Vinnie Saladino 沉浸在 UNIX 世界 4 年,VAX 世界 19 年。他拥有电气工程学士学位和计算机科学硕士学位。目前,UNIX 和 Oracle 占据了他大部分时间。他喜欢建造、钉钉子、锯木头和布线,以及制作彩色玻璃。他与他的两个孩子、两条狗和两台电脑住在一起。欢迎您通过 saladino@idt.net 向他发送评论。

加载 Disqus 评论