企業中隨之業務的逐漸增大,後端所使用的編程語言是php,系統爲LAMP/LNMP架構,須要將代碼上傳到服務器中;代碼會不斷的迭代,這就須要在業務服務器上更新代碼,一臺一臺地手動迭代很不現實,這就須要創建一個分發系統,將代碼自動分發到各個服務器上,實現自動化更新!php
所謂的分發系統,其實是經過expect這種腳本語言實現的。linux
這個分發系統首先要準備一臺模板機,更新好代碼,同時須要知道推送的多臺服務器的用戶及密碼,最後經過編寫expect腳本,藉助於rsync,登陸到各個服務器,並將代碼推送過去。該方法一樣支持命令的分發!shell
yum install -y expect
[root@dr1 sbin]# cd /usr/local/sbin [root@dr1 sbin]# vi 1.expect #! /usr/bin/expect set host "192.168.88.10" ##定義目標地址變量,變量內容爲目標主機的IP地址 set passwd "123456" ##定義目標密碼變量,變量內容爲目標主機的登陸密碼 spawn ssh root@$host ##執行shell命令,以root用戶遠程登陸 expect { ##expect代碼段用於執行交互 "yes/no" { send "yes\r"; exp_continue} ##當截取到包含yes/no的字符串時,執行花括號中的內容 "password:" { send "$passwd\r" } ##當截取到包含password的字符串時,執行花括號中的內容 } interact ##表示expect代碼段執行結束
expect代碼段中,花括號前的雙引號表明通配符,send是發送指令,\r表明回車,exp_continue表明繼續執行編程
注:expect的最外層花括號必定要與expect放在同一行,不然執行腳本會報錯。後端
chmod a+x 1.expect
./1.expect
效果測試服務器
[root@linux-5 sbin]# ./1.expect spawn ssh root@192.168.88.10 The authenticity of host '192.168.88.10 (192.168.88.10)' can't be established. ECDSA key fingerprint is SHA256:HNWPZKwLPTsAiNBW0ks7WYByXYaeSVYBSMlT28JyWQg. ECDSA key fingerprint is MD5:bb:b3:38:02:41:c8:7b:c6:71:47:cb:ce:f2:75:07:50. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.88.10' (ECDSA) to the list of known hosts. Last login: Wed Jul 11 14:14:01 2018 from 192.168.88.1 [root@linux-10 ~]# exit 登出 Connection to 192.168.88.10 closed. [root@linux-5 sbin]# ./1.expect spawn ssh root@192.168.88.10 Last login: Fri Jul 20 10:00:00 2018 from 192.168.88.5 [root@linux-10 ~]#
注:第一次遠程登陸主機,會提示輸入是否繼續,並輸入密碼,第二次登陸就直接提示password,再也不提示是否繼續,要想後續登陸也提示,清空本地的/root/.ssh/know_hosts文件便可!架構
#!/usr/bin/expect set user "root" set passwd "123456" spawn ssh $user@192.168.88.10 expect { "yes/no" { send "yes\r"; exp_continue} "password:" { send "$passwd\r" } } // 對應進入遠程主機後的[root@linux-10 ~]#最後的]# // 對於普通用戶而言,最後爲]$,使用]*均可以匹配到 expect "]*" ##當匹配到"]*"時,也就是後綴爲#或$均可以 send "touch /tmp/12.txt\r" expect "]*" send "echo 1212 > /tmp/12.txt\r" expect "]*" send "exit\r"
#!/usr/bin/expect set user [lindex $argv 0] //相似於shell內的$1 set host [lindex $argv 1] //相似於shell內的$2 set passwd "1" set cm [lindex $argv 2] //相似於shell內的$3,這裏指的是後續執行的命令 spawn ssh $user@$host expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } expect "]*" send "$cm\r" expect "]*" send "exit\r"
使用時須要指定參數ssh
# $3能夠是多條命令,使用;間隔,""包裹 ./3.expect root 192.168.88.10 "ls;free -h"
注:expect有一個超時時間,若是不設置interact或者expect eof,執行expect腳本後會馬上退出,後續命令不會繼續執行!編程語言
set timeout 能夠設置超時時間(單位爲:秒),放在expect下能夠生效測試
set timeout 5 ##5秒超時 set timeout -1 ##爲永不超時
注:set timeout放在spawn下不會生效,想要保障spawn所執行的命令不之外中斷,只能加interact或者expect eof