使用expect和rsync传输文件

使用expect和rsync传输文件 · Mar 27, 2014 clicks

最近这个项目部署在4台服务器上,虽然做了负载均衡,但是却没有做rsync服务来同步文件(那帮人水平太菜)。所以每次发布到服务器都要传4次!!!!而且中间还得通过跳板机。

1. 先做了个端口转发,通过跳板机,把本地的22001-22004这4个端口分别映射到4台服务器的sshd端口。

2. 安装expect:

sudo apt-get install expect 

expect里用的不是bash脚本,而是tcl,想练习或者测试一下代码,可以安装一下tclsh:

sudo apt-get install tcl

然后输入tclsh就进入tcl的环境了。

3. 利用expect脚本免除每次登陆都要输入密码之苦,用rsync把文件同步到服务器上。

#!/usr/bin/expect -f
#源路径,通过脚本的参数传入
set Src [lindex $argv 0]
#防止rsync在同步同名目录时,没有覆盖而是生成子目录。
#参数结尾有‘/’的为传输目录,否则为传输文件
set Dist [string trimright $Src "/"] #目标路径
set Uname www  #服务器账号
set Pwd 123456 #服务器密码
foreach Port { 22001 22002 22003 22004} {
    spawn rsync -ave "ssh -p $Port" /home/project//$Src $Uname@localhost:/data0/htdocs/www/$Dist
    expect {
         "yes/no" {send "yes\r"
         expect "*assword:" {send "$Pwd\r" }
         }
         "*assword:" {send "$Pwd\r"}
     }
     expect eof
 }
 exit
~            

只有spawn执行的命令结果才会被expect捕捉到,因为spawn会启动一个进程,只有这个进程的相关信息才会被捕捉到,主要包括:标准输入的提示信息,eof和timeout