whereis expect
-c 选项用来标明需要在执行脚本内容之前来执行的命令。这条命令(-c选项后的命令)应该用引号括起来,以免在执行时被shell分开解释 。
-c选项可能会被反复使用。多条命令可以使用同一个”-c”,命令之间需要用分号隔开。这些命令会按照它们出现的先后顺序执行。(在Expectk中,”-c”相当于”-command”)。
-d 选项允许输出调试性信息 。这些信息主要报告像expect和interact等命令执行时的内部行为。这个选项与写在脚本开头的
- f 选项指明从哪个文件中读取命令。这个选项是可选的,因为只有当使用”#!”时它才有可能被用到。而其他选项可以写在命令行中。(在Expectk中,它相当于”-file”)。
set timeout命令设置后面所有的expect命令的等待响应的超时时间为$tout(-l参数用来关闭任何超时设置)。
#!/bin/bash
expect -c "
set timeout 100
spawn /usr/bin/scp -r $bakpath root@192.168.101.49:/ var /www/html/ip_logs
expect "*password*"
send "'123456'\\r"
expect eof;"
rm $bakpath /log_ $DATE .tar.gz
#!/bin/expect
spawn ./interactive.sh 需要自动化哪一个命令
expect "Enter number:" 提供需要等待的消息
send 1\n" 发送的消息
expect "Enter name:"
send "hello\n"
expect eof 命令交互结束
-d参数调试Expect脚本:
# /usr/bin/expect -d sample_login.exp root 111111
==================== expect+[sh]for 循环执行远程主机命令
update.sh
all_web_ips="192.168.1.174 192.168.1.34"
#平滑集群内从web
for IP in $all_web_ips; do
$cur_path/hub_exp.exp $IP root 123456
done
#hub_exp.exp
#!/usr/bin/expect -f
# ====================================================================
# hub_exp.exp
# 集群内所有web交互执行
# Usage: /usr/local/shell/automation/hub_exp.exp 192.168.1.174 root 123456
# Author: zheng.dl
# 参数说明:
# $1 完全ip地址
# $2 expect账户
# $3 expect密码
# ====================================================================
set HOST [lindex $argv 0]
#set USER "root"
#set PASSWD "123456"
set USER [lindex $argv 1]
set PASSWD [lindex $argv 2]
set timeout 20
#puts $PASSWD
#exit
spawn ssh $USER@$HOST
#sleep 13
expect_before "no)?" {
send "yes\r" }
sleep 5
# 输入密码
expect "password:"
send "$PASSWD\r"
#如果想直接进入交互模式,可以直接用下面这句
#interact
#expect -timeout 1
sleep 2
expect "*$*"
send "sudo /usr/local/nginx/sbin/nginx -s reload;sudo kill -USR2 `cat /dev/shm/pid/php-fpm.pid`\r"
expect "*$*"
expect "*#*"
send "sudo /usr/local/nginx/sbin/nginx -s reload;sudo kill -USR2 `cat /dev/shm/pid/php-fpm.pid`\r"
expect "*#*"
exit
============================= 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
- 供参考。。