首页 > 代码库 > 自动化运维脚本语言之expect实践学习(1)

自动化运维脚本语言之expect实践学习(1)

一、expect简介

expect是一种简单的基于Tcl的脚本语言工具,一个可实现自动交互功能的软件套件,其功能就是进行自动化的人机交互;也能够按照脚本内容里面设定的方式与交互式程序进行“会话”的程序,根据脚本内容expect可以知道程序会提示或反馈什么内容以及什么是正确的应答;它是一种可以提供“分支和嵌套结构”来引导程序流程的解释型脚本语言。

shell功能虽然强大,但是不能实现有交互功能的多机器之间的操作例如ssh和ftp,而expect可以帮助我们来实现。

主要功能:实现自动登录远程机器并自动执行命令和shell脚本,结合定时任务可以实现完全自动化!
注意:使用不带密码的密钥验证也可以实现该功能;但没有密钥就只能用远程机器上的账号和密码!

二、expect的安装

安装方式可采用源码和rpm包等安装方式进行,在此以rpm包安装为例进行说明!
[root@expect-lab src]# cat /etc/issue
Red Hat Enterprise Linux Server release 6.2 (Santiago)
Kernel \r on an \m
[root@expect-lab src]# uname -a
Linux expect-lab 2.6.32-220.el6.i686 #1 SMP Wed Nov 9 08:02:18 EST 2011 i686 i686 i386 GNU/Linux
[root@expect-lab src]#ll
total 260

-rw-r--r-- 1 root root 262584 Mar  7  2017 expect-5.44.1.15-5.el6_4.i686.rpm
[root@expect-lab src]# rpm -ivh expect-5.44.1.15-5.el6_4.i686.rpm
warning: expect-5.44.1.15-5.el6_4.i686.rpm: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
error: Failed dependencies: libtcl8.5.so is needed by expect-5.44.1.15-5.el6_4.i686

问题:说明缺少tcl库文件,需要安装tcl软件!

[root@expect-lab src]# ll
total 2228
-rw-r--r-- 1 root root  262584 Mar  7  2017 expect-5.44.1.15-5.el6_4.i686.rpm
-rw-r--r-- 1 root root 2012712 Mar  7  2017 tcl-8.5.7-6.el6.i686.rpm

[root@expect-lab src]# rpm -ivh tcl-8.5.7-6.el6.i686.rpm
warning: tcl-8.5.7-6.el6.i686.rpm: Header V3 RSA/SHA256 Signature, key ID c105b9de: NOKEY
Preparing...        ########################################### [100%]  
1:tcl                    ########################################### [100%]
[root@expect-lab src]# rpm -ivh expect-5.44.1.15-5.el6_4.i686.rpm
warning: expect-5.44.1.15-5.el6_4.i686.rpm: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
Preparing...            ########################################### [100%]  
1:expect                 ########################################### [100%]
[root@expect-lab src]# expect
expect1.1> exit                 
#说明expect已经安装成功!

三、expect的使用说明

expect的核心命令是spawn expect send set
注意:只有在安装expect后,进入expect环境后才可以执行的expect内部命令!
spawn #调用要执行的命令或脚本
expect #等待命令提示信息的出现,也就是捕捉用户输入的提示
send #发送需要交互的值,替代了用户手动输入内容
set #设置变量值
interact #执行完成后保持交互状态把控制权交给控制台,这个时候就可以手工操作了;如果没有这一句登录完成后会退出,而不是留在远程终端上!
expect eof #这个一定要加,与spawn对应表示捕获终端输出信息终止,类似于if....endif
注意:expect脚本必须以interact或expect eof结束,执行自动化任务通常以expect eof来表示脚本任务执行完毕!
常用语法设置:
set timeout -1 #设置expect永不超时
set timeout 300 #设置expect 300秒超时,如果超过300没有expect内容出现则退出
exp_continue #继续执行接下来的交互操作
$argv 参数数组 #使用[lindex $argv n]获得从bash传递过来的参数(其中n从0开始...,分别表示第1个,第2个...参数)
cmd arg1 arg2 arg3 #说明:命令由空格分隔,cmd是命令名称,其余的是命令参数1,2,3
四、简单实例应用1:

通过expect实现非交互ssh登录,登录后并将ifconfig获取的信息重定向到文件
[root@expect-lab src]# ll
total 2232
-rw-r--r-- 1  root root  262584 Mar  7  2017 expect-5.44.1.15-5.el6_4.i686.rpm
-rwxr-xr-x 1  root root     264 Apr 18 05:06 ssh_exp
-rw-r--r-- 1  root root 2012712 Mar  7  2017 tcl-8.5.7-6.el6.i686.rpm
说明:当前目录下在执行expect脚本之前没有ip_information文件!

root@expect-lab src]# cat ssh_exp
#!/usr/bin/expect
set host "192.168.4.176" #设定远程主机ip
set passwd "passwdstr" #设定ssh登录远程主机的密码
spawn ssh root@$host #执行ssh登录
expect #expect匹配用户输入信息
{
"yes/no" { send "yes\r"; exp_continue } #匹配到""里的内容,发送yes换行并继续
"password:"{ send "$passwd\r"; exp_continue } #匹配到""里的内容,发送密码换行并继续
"#" { send "ifconfig \> /usr/local/src/ip_information\r" } #匹配到""里的内容,发送ifconfig并重定向文件
}
expect eof #结束expect
[root@expect-lab src]# ./ssh_exp    
spawn ssh root@192.168.4.176 
root@192.168.4.176‘s password:  
Last login: Thu Apr 18 05:07:11 2013 from networker.semico 
[root@expect-lab ~]# ifconfig > /usr/local/src/ip_information 
以上部分为ssh_exp脚本自动执行的部分!

[root@expect-lab src]# ll

total 2236
-rw-r--r-- 1 root root  262584 Mar  7  2017 expect-5.44.1.15-5.el6_4.i686.rpm
-rw-r--r-- 1 root root     958 Apr 18 05:18 ip_information
-rwxr-xr-x 1 root root     264 Apr 18 05:06 ssh_exp
-rw-r--r-- 1 root root 2012712 Mar  7  2017 tcl-8.5.7-6.el6.i686.rpm
说明:当前目录下在执行expect脚本之后自动生成了ip_information文件!

[root@expect-lab src]# cat ip_information  
eth0      Link encap:Ethernet  HWaddr 00:0C:29:04:49:6A             
inet addr:192.168.4.176  Bcast:192.168.4.255  Mask:255.255.255.0     
inet6 addr: fe80::20c:29ff:fe04:496a/64 Scope:Link           
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1           
RX packets:72659 errors:0 dropped:0 overruns:0 frame:0           
TX packets:38035 errors:0 dropped:0 overruns:0 carrier:0  collisions:0 txqueuelen:1000            
RX bytes:18140682 (17.3 MiB)  TX bytes:13117764 (12.5 MiB)           
Interrupt:18 Base address:0x2000
lo Link encap:Local
Loopback   inet addr:127.0.0.1  Mask:255.0.0.0           
inet6 addr: ::1/128 Scope:Host           
UP LOOPBACK RUNNING  MTU:16436  Metric:1           
RX packets:119051 errors:0 dropped:0 overruns:0 frame:0           
TX packets:119051 errors:0 dropped:0 overruns:0 carrier:0  collisions:0 txqueuelen:0            
RX bytes:55243096 (52.6 MiB)  TX bytes:55243096 (52.6 MiB)

说明:本实例通过一个较简单的expect脚本实现了ssh自动非交互登录并在登录成功后将获取的接口信息重定向到了文件ip_information!

本文出自 “Bruce_tan” 博客,请务必保留此出处http://380281.blog.51cto.com/370281/1904101

自动化运维脚本语言之expect实践学习(1)