目的
为了运维人员更好地管理批量机器,特此编写本文档。
什么是 Expect
Expect 是基于 Tcl 的相对简单的一个免费的脚本编程工具语言,用来实现自动和交互式任务程序进行通信,无需人工干预。比如:SSH、SCP 等,这些程序都需要人工与其进行交互,Expect 就可以模拟人工交互过程,自动与远端程序进行交互,从而实现自动化运维的目的。
Expect 是一个用来实现自动交互功能的软件套件。
虽然,使用 C、Python 等程序也可以实现自动交互,而 Expect 更专业、简单,跨平台支持(Linux 和 Windows),它就是为了系统管理和软件测试方面的自动交互类需求而产生的。
Expect 工作流程
Expect 的工作流程可以理解为:spawn 启动进程 -> expect 期待关键字 -> send 向进程发送字符 -> 退出结束。
安装 Expect
首先,配置好 yum 源,并能上网,然后执行:
安装后检查命令:
Expect 语法
Expect 中的命令是最重要的部分了,命令的使用语法如下:
spawn
spawn 命令是 Expect 的初始命令,它用于启动进程,之后所有 Expect 操作都在这个进程中进行,如果没有 spawn 语句,整个 Expect 就无法执行了。spawn 使用方法如下:
在 spawn 命令后面,直接加上要启动的进程、命令等信息。除此之外,spawn 还支持其他选项如:
-open启动文件进程,具体说明省略。-ignore忽略某些信号,具体说明省略。
expect
使用方法:
expect 命令用于等候一个相匹配内容的输出,一旦匹配上就执行 expect 后面的动作或命令,这个命令接受几个特有参数,用的最多的就是 -re,表示使用正则表达式的方式匹配,使用起来就像这样:
从上面的例子可以看出,expect 是依附与 spawn 命令的,当执行 ssh 命令后,expect 就匹配命令执行后的关键字 password:,如果匹配上到关键字就会执行后面包含在 {} 括号中的 send 或 exp_send 动作,匹配的动作可以放在二行,这样就不需要使用 {} 括号了,就像下面这样,实际完成的功能与上面是一样的:
expect 命令还有一种用法,它可以在一个 expect 匹配中多次匹配关键字,并给出处理动作,中需要将关键字放在一个大括号中就可以了,当然后还要有 exp_continue。
exp_send 和 send
在上面的介绍中,我们已经看到了 exp_send 命令的使用,exp_send 命令是 Expect 中的动作命令,它还有一个完成同样工作的同胞:send。exp_send 命令可以发送一些特性符号,我们看到了 \r(回车),还有一些其他的比如:\n(换行)、\t(制表符)等等,这些都与 TCL 中的特殊符号相同。
send 命令有几个可用的参数:
-i指定spawn_id,这个参数用来向不同spawn_id的进程发送命令,是进行多程序控制的关键参数。-ss 代表 slowly,也就是控制发送的速度,这个参数使用的时候要与 Expect 中的变量send_slow相关联。
exp_continue
这个命令一般用在动作中,它被使用的条件比较苛刻,看下面的例子:
在这个例子中,可以发现 exp_continue 命令的使用方法,首先它要处于一个 expect 命令中,然后它属于一种动作命令,完成的工作就是从头开始遍历,也就是说如果没有这个命令,匹配第一个关键字以后就会继续匹配第二个关键字,但有了这个命令后,匹配第一个关键字以后,第二次匹配依然从第一个关键字开始。
send_user
send_user 命令用来把后面的参数输出到标准输出中去,默认的 send、exp_send 命令都是将参数输出到程序中去的,用起来就像这样:
这个语句就可以在标准输出中打印 please input passwd: 字符了。
exit
exit 命令功能很简单,就是直接退出脚本,但是可以利用这个命令对脚本做一些扫尾工作,比如下面这样:
Expect 变量
Expect 中有很多有用的变量,它们的使用方法与 TCL 语言中的变量相同,比如:
Expect 关键字
Expect 中的特殊关键字用于匹配过程,代表某些特殊含义或状态,一般用于 expect 族命令中而不能在外面单独使用,也可以理解为事件,使用上类似于:
eof
eof(end-of-file)关键字用于匹配结束符,比如文件的结束符、FTP 传输停止等情况,在这个关键字后跟上动作来做进一步的控制,特别是 FTP 交互操作方面,它的作用很大。用一个例子来说明:
timeout
timeout 是 Expect 中的一个重要的变量,它是一个全局性的时间控制开关,可以通过为这个变量赋值来规定整个 Expect 操作的时间,注意这个变量是服务与 Expect 全局的,它不会纠缠于某个命令,即使命令没有任何错误,到时间仍然会激活这个变量,但这个时间到达以后除了激活一个开关之外不会做其他的事情,如何处理是脚本编写人员的事情,看看它的实际使用方法:
上面的处理中,首先将 timeout 变量设置为 60 秒,当出现问题的时候程序可能会停止下来,只要到 60 秒,就会激活下面的 timeout 动作,这里我打印一个信息并且停止了脚本的运行 - 你可以做更多其他的事情,看自己的意思。
在另一种 expect 格式中,我们还有一种设置 timeout 变量的方法,看下面的例子:
在 expect 命令中间加上一个小横杠,也可以设置 timeout 变量。
timeout 变量中,设置为 0 表示立即超时,-1 则表示永不超时。
生产场景 Expect 实战
自动 SCP 文件
Expect 批量分发
Expect 批量分发 SSH 密钥
Expect 批量管理
Shell 嵌套 Expect
创建密钥
本地创建密钥
传输密钥
单机传输
批量传输


所有评论(0)