Linux批量部署工具Expect


  既然沒有遇到過,做好准備總是好的。這是自己送給自己的話,現在運維做自動話越來越多,自己就學以下,記錄筆記。目前主流的有puppet、Expect、pssh等等,今天就用Expect做自動部署和日常管理維護。

一、Expect簡介

      expect是一種能夠按照腳本內容里面設定的方式與交互式程序進行“會話”的程序。根據腳本內容,Expect可以知道程序會提示或反饋什么內容以及什么是正確的應答。它是一種可以提供“分支和嵌套結構”來引導程序流程的解釋型腳本語言。
     我們熟知的shell編程功能雖然很強大,但是不能實現有交互功能的多機器之前的操作,例如ssh和scp等。而expect可以幫助我們來實現。

二、安裝

[root@Server ~]# yum -y install expect

三、Expect使用

這里使用Expect批量管理和部署服務器大致分為兩個步驟,使用for循環讀取服務器IP、密碼列表並取值,遠程執行命令。如下需求,在兩台服務器上執行自己命令mkdir /tmp/`date +%Y%m%d`,看下面實現方法。

首先定義一個expect登錄腳本:

1、login.exp,內容如下:

 1 [root@Server ~]# vi /data/sh/login.exp 
 2 
 3 #!/usr/bin/expect -f
 4 set ip [lindex $argv 0 ]#讀取ip
 5 set passwd [lindex $argv 1 ]#讀取密碼
 6 set command [lindex $argv 2]#命令
 7 set timeout 10#登錄后下次執行命令間隔
 8 spawn ssh root@$ip#spawn   意思是執行命令,expect內命令,shell中不存在
 9 expect {
10 "yes/no" { send "yes\r";exp_continue }#選擇yes
11 "password:" { send "$passwd\r" }#讀取
12 }
13 expect "*#*" { send "$command\r" }#執行命令
14 expect eof

2、創建批量執行腳本auto_exec.sh

[root@Server ~]# vi auto_exec.sh 

#!/bin/sh
CMD="$*"
for i in `awk '{print $1}' passwd.txt`#fou循環讀取ip
do
    j=`awk -v I="$i" '{if(I==$1)print $2}' passwd.txt`#密碼
    expect /data/sh/login.exp  $i  $j  "$CMD"#執行
done

3、建立批量IP、密碼文件

1 [root@Server ~]# vi passwd.txt 
2 
3 192.168.17.135  123456
4 192.168.17.128  123456
5 192.168.17.136  123456

四、測試腳本

直接執行:

[root@Server ~]# /bin/sh auto_exec.sh "mkdir -p /tmp/`date +%Y%m%d`"

登錄三台服務器在/tmp下有日期文件

五、SCP遠程拷貝

如果需要遠程推送文件,重新建立文件login.scp相關參數和auto_exec.sh變量:

1、login.scp內容如下:

[root@Server ~]# vi login.scp 

#!/usr/bin/expect -f
set ip [lindex $argv 0 ]
set passwd [lindex $argv 1 ]
set src_file [lindex $argv 2]
set des_dir [lindex $argv 3]
set timeout 1
spawn scp -r $src_file root@$ip:$des_dir
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$passwd\r" }
}
expect "#*"
expect eof

2、auto_exec.sh腳本內容如下:

[root@Server ~]# vi auto_exec.sh

#!/bin/sh
read -p "Please Enter insert Source File or DIR: " src_file
echo ======================================================
sleep 1
read -p "Please Enter insert Destination DIR: " des_dir
for i in `awk '{print $1}' passwd.txt`
do
    j=`awk -v I="$i" '{if(I==$1)print $2}' passwd.txt`
    expect login.scp  $i  $j $src_file $des_dir
done

密碼保持不變即可。

[root@Server ~]# /bin/sh auto_exec.sh
Please Enter insert Source File or DIR: login.scp#本地文件
======================================================
Please Enter insert Destination DIR: /home
spawn scp -r login.scp root@192.168.17.135:/home#發送到客戶端的文件

六、一鍵安裝expect、scp批量auto_exec.sh腳本:

#!/bin/sh 
if
  [ ! -e /usr/bin/expect ];then
  yum  install expect -y 
fi
#Judge passwd.txt exist 
if
  [ ! -e ./passwd.txt ];then
  echo -e "The passwd.txt is not exist......Please touch ./passwd.txt ,Content Example:\n192.168.1.11 passwd1\n192.168.1.12 passwd2"
  sleep 2 &&exit 0 
fi
#Auto Tuoch login.exp File 
cat >login.exp <<EOF 
#!/usr/bin/expect -f 
set ip [lindex \$argv 0 ] 
set passwd [lindex \$argv 1 ] 
set src_file [lindex \$argv 2] 
set des_dir [lindex \$argv 3] 
set timeout 1 
spawn scp -r \$src_file root@\$ip:\$des_dir 
expect { 
"yes/no" { send "yes\r";exp_continue } 
"password:" { send "\$passwd\r" } 
} 
expect "#*"
expect eof 
EOF 
##Auto exec shell scripts 
read -p "Please Enter insert Source File or DIR: " src_file 
echo ====================================================== 
sleep 1 
read -p "Please Enter insert Destination DIR: " des_dir 
for i in `awk '{print $1}' passwd.txt` 
do
    j=`awk -v I="$i" '{if(I==$1)print $2}' passwd.txt` 
    expect ./login.exp  $i  $j $src_file $des_dir 

就是以上幾個腳本的合成。

以下是expect用法

1. [#!/usr/bin/expect] 

這一行告訴操作系統腳本里的代碼使用那一個shell來執行。這里的expect其實和linux下的bash、windows下的cmd是一類東西。 

注意:這一行需要在腳本的第一行。 

2. [set timeout 30] 

基本上認識英文的都知道這是設置超時時間的,現在你只要記住他的計時單位是:秒   。timeout -1 為永不超時

3. [spawn ssh -l username 192.168.1.1] 

spawn是進入expect環境后才可以執行的expect內部命令,如果沒有裝expect或者直接在默認的SHELL下執行是找不到spawn命令的。所以不要用 “which spawn“之類的命令去找spawn命令。好比windows里的dir就是一個內部命令,這個命令由shell自帶,你無法找到一個dir.com 或 dir.exe 的可執行文件。 

它主要的功能是給ssh運行進程加個殼,用來傳遞交互指令。 

4. [expect "password:"] 

這里的expect也是expect的一個內部命令,有點暈吧,expect的shell命令和內部命令是一樣的,但不是一個功能,習慣就好了。這個命令的意思是判斷上次輸出結果里是否包含“password:”的字符串,如果有則立即返回,否則就等待一段時間后返回,這里等待時長就是前面設置的30秒 

5. [send "ispass\r"] 

這里就是執行交互動作,與手工輸入密碼的動作等效。 

溫馨提示: 命令字符串結尾別忘記加上“\r”,如果出現異常等待的狀態可以核查一下。 

6. [interact] 

執行完成后保持交互狀態,把控制權交給控制台,這個時候就可以手工操作了。如果沒有這一句登錄完成后會退出,而不是留在遠程終端上。如果你只是登錄過去執行 

7.$argv 參數數組

expect腳本可以接受從bash傳遞過來的參數.可以使用[lindex $argv n]獲得,n從0開始,分別表示第一個,第二個,第三個....參數

參考來源:http://www.linuxidc.com/Linux/2013-08/88660.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM