需求:開發人員開發的代碼發佈到線上環境中(其實後面用到jenkins纔是真正的98k)nginx
expect可讓咱們實現自動登陸遠程機器,而且能夠實現自動遠程執行命令。固然如果使用不帶密碼的密鑰驗證一樣能夠實現自動登陸和自動遠程執行命令。但當不能使用密鑰驗證的時候,咱們就沒有辦法了。因此,這時候只要知道對方機器的帳號和密碼就能夠經過expect腳本實現登陸和遠程命令。shell
分發準備:模板腳本、服務器ip、用戶名、密碼、expect腳本vim
yum install -y expectbash
expect腳本登陸機器:服務器
vim 1.expect #!/usr/bin/expect set host "192.168.133.132" #鏈接到主機 set passwd "123456" #密碼 spawn ssh root@$host #spawn調用shell命令ssh(登陸),「set host」和「set passwd」爲expect定義的兩個變量 expect { "yes/no" { send "yes\r"; exp_continue} #ssh首次遠程登陸一臺主機是會提示yes/no,吧yes發送過去;"\r「表示回車 "password:" { send "$passwd\r" } #若是提示passwd須要把密碼發送過去,用戶交互,"\r「表示回車 } interact #interact的做用是停留在遠程機器上,不退出 #腳本結束符號:expect eof——執行結束後暫停幾秒鐘後退出 #若是不加任何結束符號,命令執行完後立刻退出
注意的是須要755權限,即chmod a+x 1.expectssh
執行該腳本使用:./1.expectspa
vim 2.expect #!/usr/bin/expect set user "root" set passwd "123456" spawn ssh $user@192.168.133.132 expect { "yes/no" { send "yes\r"; exp_continue} "password:" { send "$passwd\r" } } expect "]*" #匹配到「]」指的是登陸成功後左邊的用戶信息的右括號,意思是登陸成功後執行下面的命令 send "touch /tmp/12.txt\r" "\r「表示回車,而後又匹配到左邊的的用戶信息括號 expect "]*" send "echo 1212 > /tmp/12.txt\r" "\r「表示回車,而後又匹配到左邊的的用戶信息括號 expect "]*" send "exit\r"
vim 3.expect #!/usr/bin/expect #調用內部參數,用戶名ip密碼,在執行的時候直接調用 set user [lindex $argv 0] set host [lindex $argv 1] set passwd "123456" set cm [lindex $argv 2] #這個是第三個參數,就是要執行的命令,好比ls spawn ssh $user@$host expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } expect "]*" send "$cm\r" expect "]*" send "exit\r" #若是須要執行多條命令使用;分隔和雙引號,好比「ls;w;cat 1.txt」 #expect存在超時時間,不適合運行vmstart這種命令 #若是想要修改超時時間,在send "$cm\r"下一行加上 set timeout -1 永久不超時 set timeout 5 五秒時間推出
vim 4.expect #!/usr/bin/expect set passwd "123456" spawn rsync -av root@192.168.204.137:/tmp/12.txt /tmp/ #把遠程機器上的12.txt同步到本機 expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } expect eof #腳本結束符號:expect eof——執行結束後暫停幾秒鐘後退出
vim 5.expect #!/usr/bin/expect set passwd "123456" set host [lindex $argv 0] set file [lindex $argv 1] spawn rsync -av $file root@$host:$file #file寫絕對路徑 expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } expect eof chmod a+x 5.expect touch 1.txt ./5.expect 192.168.133.132 "/tmp/1.txt"
這裏思路爲首先寫expect腳本,而後提供參數,最後使用shell腳本實現分發功能code
#第一步寫expect腳本,最後shell也是調用到了這裏來實現功能 vim rsync.expect #!/usr/bin/expect set passwd "123456" set host [lindex $argv 0] set file [lindex $argv 1] #這裏指的對應IP和文件列表,在最後的shell腳本中來實現 spawn rsync -av --files-from=$file / root@$host:/ #若是不能保證對方機器有相同路徑加上-avR expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } expect eof
#第二步提供要被傳送的文件的集合,也就是exoect腳本的第二個參數file vim list.txt /root/shell/1.sh ... ... #該文件下可添加多個文件,這個就是要傳送的文件了
#第三步定義對應ip的內容,也就是expect的host參數 vim iplist.txt 192.168.133.132 192.168.133.133 ...... #此處IP(主機)密碼要和rsync.expect腳本中一致。爲了不密碼泄露的風險,可使用密鑰認證的方法
#最後shell腳本實現功能 vim rsync.sh #!/bin/bash for ip in `cat iplist.txt` do echo $ip ./rsync.expect $ip list.txt done #該腳本做用是遍歷文件和ip列表
#第一步expect腳本調用host和具體的命令$cm vim exe.expect #!/usr/bin/expect set host [lindex $argv 0] #第一個變量 set passwd "123456" 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" #該腳本做用是遠程執行命令 chmod a+x exe.expect
#而後定義shell腳本,指定ip和使用的命令 #執行此腳本的目的是一次性多臺機器執行相同命令,全部shell中定義需執行的命令 vim exe.sh #!/bin/bash for ip in `cat iplist.txt` do echo $ip ./exe.expect $ip "w;free -m;ls /tmp" done #該腳本的做用是調用iplist.txt文件中的IP和exe.expect腳本