Linux使用expect實現遠端拷貝檔案

進擊的巨喵發表於2015-11-18

1.背景

公司有個專案打算用Nginx叢集的方式部署在三臺伺服器共 7個tomcat裡,這樣更新的時候如果一個一個去更新顯然會很麻煩,現在打算用執行命令的方式把要需要更新的檔案直接拷貝覆蓋到那7個tomcat裡去(不知道有沒有比這種更簡便的更新方式,如果有還望賜教)。一開始打算先把要更新的檔案拷貝在其中一個主伺服器的目錄下,然後執行shell指令碼用cp和scp的命令把檔案拷貝到當前伺服器和另外兩個伺服器的tomcat裡,但是在執行到scp命令的時候會提示需要輸入系統使用者的密碼,最後發現使用expect可以避免這個麻煩。

2.安裝

安裝的方式有很多,這裡使用比較簡便的rpm方式來安裝,安裝之前需要先檢查一下系統是否已經安裝過expect:

#檢視是否有安裝過tcl(expect需要依賴tcl)

rpm -qa | grep tcl

#檢視是否有安裝過expect

rpm -qa | grep expect

如果有輸出顯示已經安裝過了,那就不用安裝了。

安裝需要準備的工具:

先安裝tcl:

rpm -ivh tcl-*

再安裝expect:

rpm -ivh expect-5.44.1.11-1.240.x86_64.rpm 

3.指令碼

dealrsync.sh:把本機專案拷貝到本機的tomcat,迴圈執行遠端拷貝的expect指令碼

#/bin/sh
#同步各伺服器的專案

#原始檔
src_file=testproject

#把專案複製到本主機伺服器的tomcat
cp -pr $src_file /home/was/webtest/tom1
cp -pr $src_file /home/was/webtest/tom2
cp -pr $src_file /home/was/webtest/tom3

#把專案複製到其他主機伺服器的tomcat

#格式:ip 使用者名稱 密碼 目標檔案地址
remoteserver_list="remoteserver_list.conf"
cat $remoteserver_list | while read line

do
  host_ip=`echo $line|awk '{print $1}'`
  username=`echo $line|awk '{print $2}'`
  password=`echo $line|awk '{print $3}'`
  dest_file=`echo $line|awk '{print $4}'`
  ./remotescp.sh $src_file $username $host_ip $dest_file $password
done

rsyncfiles.sh:把本地檔案拷貝到遠端伺服器

#!/usr/bin/expect
if {$argc < 2} {
    send_user "usage: $argv0 src_file username ip dest_file password\n"
    exit
}
set src_file [lindex $argv 0]
set username [lindex $argv 1]
set host_ip [lindex $argv 2]
set dest_file [lindex $argv 3]
set password [lindex $argv 4]

spawn scp -pr $src_file $username@$host_ip:$dest_file
expect {
        "(yes/no)?"
        {
                send "yes\n"
                expect "*assword:" {send "$password\n"}
        }
        "*assword:"
        {
                send "$password\n"
        }
}
expect "100%"
expect eof

remoteserver_list.conf:遠端主機伺服器地址列表(如果密碼裡有特殊字元則需要轉義)

192.168.1.11 root ****** /home/was/webtest/tom4
192.168.1.11 root ****** /home/was/webtest/tom5
192.168.1.12 root ****** /home/was/webtest/tom6
192.168.1.12 root ****** /home/was/webtest/tom7


相關文章