日期:2014-05-16  浏览次数:20997 次

linux expect自动和交互式任务进行通信

我们通过Shell可以实现简单的控制流功能,如:循环、判断等。但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能。而Expect就使用来实现这种功能的工具。

  Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。Expect的作者Don Libes在1990年 开始编写Expect时对Expect做有如下定义:Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools)。使用它系统管理员 的可以创建脚本用来实现对命令或程序提供输入,而这些命令和程序是期望从终端(terminal)得到输入,一般来说这些输入都需要手工输入进行的。 Expect则可以根据程序的提示模拟标准输入提供给程序需要的输入来实现交互程序执行。甚至可以实现实现简单的BBS聊天机器人。 :)

  Expect是不断发展的,随着时间的流逝,其功能越来越强大,已经成为系统管理员的的一个强大助手。Expect需要Tcl编程语言的支持,要在系统上运行Expect必须首先安装Tcl。

  二、Expect工作原理

  从最简单的层次来说,Expect的工作方式象一个通用化的Chat脚本工具。Chat脚本最早用于UUCP网络内,以用来实现计算机之间需要建立连接时进行特定的登录会话的自动化。

  Chat脚本由一系列expect-send对组成:expect等待输出中输出特定的字符,通常是一个提示符,然后发送特定的响应。例如下面的 Chat脚本实现等待标准输出出现Login:字符串,然后发送somebody作为用户名;然后等待Password:提示符,并发出响应 sillyme。

  引用:Login: somebody Password: sillyme

  这个脚本用来实现一个登录过程,并用特定的用户名和密码实现登录。

  Expect最简单的脚本操作模式本质上和Chat脚本工作模式是一样的。


?

?

?

利用expect脚本进行项目的自动远程部署 
基本原理是
1.首先进行本地的打包,如排除不必要的项目文件和临时文件,根据服务器的不同进行配置文件的个性化修改和拷贝
2.然后通过scp等方式将压缩包传到远程部署服务器上
3.在远程服务器上进行部署操作
以上步骤均通过交互式的脚本进行,减少人工干预,通过CI系统(如hudson)可以实现一键编译发布或自动联编发布的效果

要注意的是脚本被调用的用户和远程操作的权限是否正确。
处于安全考虑,建议不要在脚本中进行su等获取其他用户权限的操作,而是指定脚本本地和远程的操作用户和权限。
比如,hudson是www用户启动运行,部署脚本也最好赋予www用户的所有和执行权。
另如,远程php服务器使用www启动运行,部署脚本直接使用www用户进行远程拷贝和部署。

以下是脚本

#!/usr/bin/expect
###########################################
##将项目远程部署到测试服务器上#
##
###########################################


#-----------设置脚本变量和参数----------------

set sitename [lindex $argv 0]
set remotehost    [lindex $argv 1]
set remoteip [lindex $argv 2]
set buildnumber [lindex $argv 3]
#ssh的用户名
set username "www"
#ssh的密码
set passwd "123456"
set enddate [timestamp -format %Y%m%d]
set timeout 300


#------------------本地打包------------------------------------------------------
#---------------根据部署的服务器不同个性化打包不同的项目配置文件-----------------
system mkdir -p ./tmp
system rm -fR ./tmp/*
system cp -r ./Application/$sitename ./tmp/
system cp -r ./Configuration/$remotehost/$sitename/* ./tmp/$sitename/application/config/
cd ./tmp/$sitename
#注意排除项目文件和svn文件
system tar -zcf $enddate\_$buildnumber.tar.gz  --exclude-caches --exclude=web.config --exclude=.svn --exclude='.buildpath|.config|.setting|.project' *


#---------------将打包的文件通过scp拷贝到测试服务器上----------------

spawn scp $enddate\_$buildnumber.tar.gz $username@$remoteip:/wwwroot/
expect {
        "*(yes)*" {
                send "yes\r"
		exp_continue
        }
	"*password:*" {
                send "$passwd\r"
		exp_continue
        }
	eof {}
}


#-----------------------远程执行部署流程---------------------

spawn ssh $username@$remoteip
expect {
        "*(yes)*" {
                send "yes\r"
		exp_continue
        }
	"*password:*" {
                send "$passwd\r"
		exp_continue
        }
	"www@*" {
		send "mkdir -p /wwwroot/$sitename/$enddate\_$buildnumber\r"
		sleep 1
		send "cd /wwwroot/$sitename/$enddate\_$buildnumber \r"
		sleep 1
		send "tar -zxf ../../$enddate\_$buildnumber.tar.gz \r"
		sleep 1
		send "rm -f /webdata1/$sitename \r"
		sleep 1
		send "ln -s /wwwroot/$sitename/$enddate\_$buildnumber /webdata1/$sitename \r"
		sleep 1
		send "rm -f ../../$enddate\_$buildnumber.tar.gz \r"
		sleep 1
		send "exit\r"
		exp_continue
	}
	eof {}
}

#-------------------本地清理----------------------
cd ../
system rm -Rf *


exit
供参考。。
?

?

?

?

?

?

?

?

?

?

?

?

?

?

?