20.27 分發系統介紹
20.28 expect腳本遠程登陸
20.29 expect腳本遠程執行命令
20.30 expect腳本傳遞參數
20.31 expect腳本同步文件
20.32 expect腳本指定host和要同步的文件
20.33 構建文件分發系統
20.34 批量遠程執行命令
擴展:
shell多線程 http://blog.lishiming.net/?p=448
給你提供一本電子書 連接:http://pan.baidu.com/s/1mg49Taw 密碼:yk4b
shell習題作一下 http://www.apelearn.com/study_v2/chapter15.html#shllhtml
現在一些比較大的企業,大都使用了負載均衡,而有時由於一些程序要更改,或者有些bug要修改,快速更新代碼等,若是僅是幾臺server的話,很簡單,把已經改好的程序拷過去,或者rsync遠程推送,再或者網上NFS共享一下就能夠了;但若是有幾十臺幾百臺,那樣的方法會太繁瑣,此時就能夠用expect來批量實現分發任務。shell
expect:一個實現自動交互功能的軟件套件,基於Tcl的一種腳本語言,具備簡單的語法;vim
功 能 :實現自動登陸遠程機器,並自動執行命令;和shell腳本結合,能夠實現徹底自動化;bash
注 意:如果使用不帶密碼的密鑰驗證一樣能夠實現自動登陸和自動遠程執行命令。但當不能使用密鑰驗證的時候,咱們就沒有辦法了。因此,這時只知道對方機器的帳號和密碼能夠經過expect腳本實現登陸和遠程命令。服務器
001上進入/usr/local/sbin/,建立一個expect腳本,若是帶有註釋寫入腳本會報錯多線程
#! /usr/bin/expect set host "192.168.183.33" #設置鏈接主機,定義變量host set passwd "qwertyuiop" #設置密碼,定義變量passwd spawn ssh root@$host #執行命令 expect { "yes/no" { send "yes\r"; exp_continue} #假如第一次登錄,須要yse,而後回車,繼續執行 "password:" { send "$passwd\r" } #輸入密碼 } interact #結束執行
代碼解釋: #! /usr/bin/expect 這一行告訴操做系統腳本里的代碼使用那一個shell來執行。負載均衡
在expect下 定義變量,用 set,好比 定義變量a爲1 :set a 1ssh
expect 使用expect語句進行交互網站
\r表示回車ui
exp_continue 表示繼續 \r 表示換行 interact 繼續停留在這臺機器,不退出。
interact表示繼續交互,會繼續停留在遠程的機器上不退出,若是使用expect eof,會在遠程機器上暫停1-2秒在退出
上面腳本中的yes或no,即表示下面操做
若是登錄過就不在提示輸入yes或no,須要在vim /root/.ssh/known_hosts刪除對應機器的ip就會在遠程登錄時出現提示
或者 > /root/.ssh/known_hosts //清空
給腳本執行權限: chmod a+x 1.expect
./1.expect 執行腳本後,便可自動鏈接到002
不清空known_hosts下次鏈接則不提示yes或no
自動遠程登陸後,執行命令並退出,給執行權限chmod a+x 2.expect
#!/usr/bin/expect set user "root" 設置用戶爲 root set passwd "qwertyuiop" root的密碼 spawn ssh $user@192.168.183.33 鏈接遠程機器002 expect { expect腳本內容 "yes/no" { send "yes\r"; exp_continue} "password:" { send "$passwd\r" } } expect "]*" 遇到右側方括號執行下面命令,root用戶時是'#',普通用戶是'$',此處用'*',不作區分 send "touch /tmp/12.txt\r" 在/tmp下建立12.txt;回車 expect "]*" 上一語句執行完,遇到右側方括號,執行下面 send "echo 1212 > /tmp/12.txt\r" 把1212寫入12.txt,回車 expect "]*" send "exit\r" 輸入exit,退出,回到001機器
執行腳本,到002查看,文件和內容都執行,建立時間也沒問題
expect腳本傳遞過來的參數可使用[lindex $argv n]得到,n從0開始,分別表示第一個,第二個,第三個….參數
#!/usr/bin/expect set user [lindex $argv 0] 第一個參數 set host [lindex $argv 1] 第二個參數 set passwd "qwertyuiop" set cm [lindex $argv 2] 第三參數 spawn ssh $user@$host expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } expect "]*" send "$cm\r" expect "]*" send "exit\r"
給予可執行權限,並定義參數後執行腳本
chmod a+x 3.expect ./3.expect root 192.168.183.33 "ls"
參數中能夠定義多個命令:如執行pwd、w、ls -l、vmstat 1等,命令之間用分號隔開
./3.expect root 192.168.183.33 "pwd;w;ls -l;vmstat 1"
也能夠都使用參數代替,可是執行的時候要定義對應參數後執行腳本
在一臺機器上把文件同步到多臺機器上;核心命令,就是用的rsync服務
#!/usr/bin/expect set passwd "qwertyuiop" spawn rsync -av root@192.168.183.33:/tmp/12.txt /tmp/ expect { "yes/no" { send "yes\r"} "password:" { send $passwd\r} } expect eof
expect eof 語句解釋:
spawn執行的命令結果,會被expect捕捉到。由於spawn會啓動一個進程,只有這個進程的相關信息纔會被捕捉到,主要包括:標準輸入的提示信息,eof和timeout。
在這裏eof是必須去匹配的,在spawn進程結束後會向expect發送eof,若是expect沒有匹配,那麼會當即退出遠程登陸,即操做失敗。
chmod a+x 4.expect
同步完成
set timeout 定義超時時間(單位爲 秒) -1 爲永遠不超時 這裏要同步的文件,必要要寫絕對路徑
此腳本只能同步單個文件
#!/usr/bin/expect
set passwd "qwertyuiop"
set host [lindex $argv 0]
set file [lindex $argv 1]
spawn rsync -av $file root@$host:$file
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect eof
chmod a+x 5.expect
需求背景
對於大公司而言,確定時不時會有網站或者配置文件更新,並且使用的機器確定也是好多臺,少則幾臺,多則幾十甚至上百臺。因此,自動同步文件是相當重要的。
實現思路
首先要有一臺模板機器,把要分發的文件準備好,而後只要使用expect腳本批量把須要同步的文件分發到目標機器便可。
核心命令
rsync -av --files-from=list.txt / root@host:/
使用rsync 的 --files-from參數,能夠實現調用文件裏面的列表,進行多個文件遠程傳輸,進而實現文件分發文件分發系統的實現。
編寫rsync.expect 腳本, chmod a+x rsync.expect
#!/usr/bin/expect set passwd "jiangbin" set host [lindex $argv 0] set file [lindex $argv 1] spawn rsync -avR --files-from=$file / root@$host:/ # 上傳文件的列表是$file,須要在list當中去定義; --file-from指定文件列表路徑 -R表示同步時會把不存在的目錄進行建立 expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } expect eof
建立file.list 須要同步的文件列表
/tmp/file.list
由於實現分發系統,是由於須要分發的機器數量過大,因此,定義好了 list 文件列表之後, 還須要配置 ip 的列表文件
幾臺機器的密碼要相同,若是設置了祕鑰,能夠把輸入密碼的步驟省略
/tmp/ip.list 把本地的數據同步到列表中的兩臺機器上
建立一個rsync的shell腳本,腳本的目的:遍歷全部的server和list中的文件能夠同步到每臺服務器。
#!/bin/bash for ip in `cat /tmp/ip.list` do echo $ip ./rsync.expect $ip /tmp/file.list done
此時查看下發數據的兩臺機器,已經有了下發的數據,而且會把兩臺機器上不存在的目錄進行建立,新建立目錄中的文件也會下發
當同步完代碼後有可能須要批量地重啓服務,所以還須要批量遠程執行命令,相似於自動化。 這裏是用expect編寫執行命令的腳本並用shell腳原本批量調用它。
建立exe.expect,chmod a+x exe.expect
#!/usr/bin/expect set host [lindex $argv 0] set passwd "jiangbin" set cm [lindex $argv 1] spawn ssh root@$host expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } expect "]*" send "$cm\r" expect "]*" send "exit\r"
再新建exe.sh的shell腳本,用來調用exe.expect腳本
#!/bin/bash for ip in `cat /tmp/ip.list` do ./exe.expect $ip "ls" 調用exe.expect腳本,此處只執行ls命令,能夠寫成"w;free -m;ls /tmp"執行多個命令 done