首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

大型企业 Unix 服务器的自动化运维 (2)

大型企业 Unix 服务器的自动化运维 (2)

Expect 脚本自动化运维考虑如下案例情况:有一批客户服务器需要做一个变更,将 sudoer 配置文件从 /etc/sudoer 目录搬移备份到 /usr/local/etc/sudoer 目录,由于该配置文件比较重要,需要 root 权限才能执行搬移操作,该客户服务器也采用 SSHD 协议,不允许 ftp/telnet 等的登录。
该情况下上文所提到的第二种方式 Java 开源包已不适用,因在 shell 进程下当切换用户尤其是 sudo 到 root 时,会 fork 一个新的进程,sudo 到 root 的会话在新的进程中进行,而 Java 开源包是限定在一个会话中的,执行 sudo 操作后,新的进程已经脱离了 Java 开源包的控制,这时候再试图用 Java 开源来执行后续命令,将会报错。
此类需要切换用户的情况下我们采用 Expect 脚本来进行模拟交互。
在这里将 Expect 脚本简介如下:
Expect 使用 Tcl 作为语言核心。不仅如此,不管程序是交互和还是非交互的,Expect 都能运用。这是一个小语言和 Unix 的其他工具配合起来产生强大功能的经典例子。Expect 是一个控制交互式程序的工具。它解决了上述需要用户角色转换的问题,用非交互的方式实现了所有交互式的功能。关于 Tcl 语言的内容超出了本文的范畴,有兴趣的读者请参见参考资源。
Expect 被设计成专门针和交互式程序的交互。一个 Expect 程序员可以写一个脚本来描述程序和用户的对话。接着 Expect 程序可以非交互的运行“交互式”的程序。写交互式程序的脚本和写非交互式程序的脚本一样简单。Expect 还可以用于对对话的一部分进行自动化,因为程序的控制可以在键盘和脚本之间进行切换。
简单的说,Expect 脚本是用一种解释性语言写的。( 也有 C 和 C++ 的 Expect 库可供使用,但这超出了本文的范围 ).Expect 提供了创建交互式进程和读写它们的输入和输出的命令。它是在 Tcl 基础上创建起来的,并提供了一些 Tcl 所没有的命令。
关于 Expect 脚本的详细介绍,有兴趣的读者可以参考 文章。
编写 Expect 脚本的基本方式如下:
表 1. Expect 脚本基本使用示例[td]
Expect 命令作用使用示例
spawn 激活一个 Unix 程序来进行交互式的运行 .
spawn ssh 192.168.1.2
send 向进程发送字符串 send "sudo -s\r"
set 给 Expect 脚本中的变量赋值 set username “joe”
expect 等待进程收到的远程主机的输出,并匹配对应的字符串 , 一旦匹配,执行后续的操作 expect { "yes/no"  send "yes" ;}

Expect 还能理解一些特殊情况,如超时和遇到文件尾。  :set timeout 60  ;expect eof
我们以上述的实例作为例子,来看看 Expert 脚本如何实现自动化登陆并 sudo 到 root,然后搬移文件的功能。
Expect 脚本 autoMove 示例如下:
清单 3. autoMove.sh 脚本示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/expect
# 导入 Expect 类库
set hostname [lindex $argv 0]
# 设置操作的远程主机,$argv 类似 Shell 函数中的接收参数 [lindex $argv 0]
# 则表示第一个接收参数 , 例如 expectExample.sh host1
set username [lindex $argv 1]
# 同上,第二个接收参数为登陆用户名
set passwd [lindex $argv 2]
# 同上,第三个接收参数为登陆用户密码
set timeout 60
# 设置等待超时为 60 秒
spawn  ssh $username@$hostname
# 使用 spawn 命令来激活 ssh 程序,模拟终端的输出将能够被 Expect 所读取,模拟终端也能从 send 输入到远程主机
expect {
          "yes/no" {send "yes ";exp_continue}
          "Password:" {send "$passwd ";}
}
#Expect 语句等待远程主机的字符串匹配,当匹配到了“yes/no”
#则执行后面的操作 .expect 搜索模式"*password:",其中 * 允许匹配
# 任意输入,所以对于避免指定所有细节而言是非常有效的。如果远程主机没有 action,
#所以 Expect 检测到该模式后就继续运行。  一旦接收到提示后,下一行就就把密码送给当前进程。
send "sudo -s\r"
expect  "Password:"  {send "$newpasswd\r"}
# 执行 sudo 用户角色转换操作

send "copy /etc/sudoers /usr/local/etcsudoers\r"
# 执行实际运维操作

send "exit\r "
send "exit\r "
expect eof {exit 1}




由上我们可以看出 Expect 使用伪终端来和派生的进程相联系。伪终端提供了终端语义以便程序认为他们正在和真正的终端进行 I/O 操作。使用 Expect 等待远程主机的响应并匹配需要的字符串,当匹配到后执行 send 操作向远程主机发送命令,set 操作为赋值,脚本的编写于通常的 Shell 脚本很类似,相当简洁和实用。
在 AIX ,Solairs 的 Unix 平台环境下 Expect 是默认安装的,Linux 需要安装对应的 rpm 包。
总结和展望以上分析了大型企业服务器的自动化脚本运维,通过不同的案例分别介绍了 shell 管道,Java SSHD 开源包和 Expect 脚本三种方式的自动化运维。三种方式针对不同的业务需求及客户服务器实际环境,有很强的实用性和操作性。可以满足绝大多数企业服务主机的自动化运维工作内容,三种方式的代码示例稍作修改,即可直接用于实际的生产主机日常运维工作中。
如今随着 IT 运维管理工作的复杂度和难度的大大增加,将纯粹的人工操作变为一定程度的自动化管理是一个必然趋势。未来的 IT 自动化运维必将更加专业化、标准化和流程化。通过自动化运维监控,系统能及时发现故障隐患,主动的告诉用户需要关注的资源,以达到防患于未然。通过自动化运维诊断,能最大限度地减少维修时间,提高服务质量。
返回列表