天天看點

Expect-自動化互動

目錄:

1.什麼是Expect?

2.Expect程式工作流程

3.安裝expect軟體

4.先看一個expect小執行個體

5.Expect文法

5.1 spwan

5.2 expect

5.3 exp send t send

5.4 exp continue

5.5 send user

5.6 exit

6.expect變量

7.Expect關鍵字

7.1 eof

7.2 timeout

8.生産場景expect實戰

8.1 實戰1:使用expect實作批量分在/etc/hosts檔案

8.2 實戰2:使用expect實作批量分發ssh密鑰檔案

8.3 實戰3:使用expect實作批量檢視客戶機負載,記憶體

9.有關expect的說明

Expect是基于Tcl的相對簡單的一個免費的腳本程式設計語言,用來實作自動和互動式任務程式進行通信,無需人的手工幹預。如ssh,ftp等,這些程式正常情況都需要手工與它們進行互動,而使用expect就可以模拟人手工互動的過程,實作自己的無端的程式互動,進而達到自動化運維的目的。

Expect是一個用來實作自動互動功能的軟體套件(Expect is a software suite for automaing interactive tools)

雖然,使用C,perl等一樣可以實作這樣的互動功能,然而expect做的更專業出色,簡單,而且除支援unit/linux平台外,還支援windows,它就是為系統管理和軟體測試方面的自動互動類需求而産生的。

Expect的工作流程可以了解為,spawn啟動程序-->expect期待關鍵字-->send向程序發送字元-->退出結束

3.安裝Expect軟體

首先,配置好yum安裝源,并且確定機器可以上網,然後執行yum instal expect -y即可安裝expect軟體。

安裝完後檢視結果:

Expect-自動化互動

4.先看一個Expect小執行個體

#vim ssh164.exp  (注意字尾為exp)

#!/usr/bin/expect(指定解釋此腳本的shell)

spawn ssh 192.168.50.164 /sbin/ifconfig eth0(spawn:指定要執行的語句)

set timeout 60(設定逾時時長,意思是要連接配接的IP,指定時間内無響應時,自斷開)

expect "*password:"(比對互動式提示的字元)

send "happy52121\n"(設定發送密碼)

expect eof()

exit(執行後退出)

Expect-自動化互動

#chmod 700 ssh164.ex (添加執行權限)

#./ssh164.exp(從下圖可以看出,無需要輸入密碼自動執行成功)

#expect ssh164.exp(這種方法也可以執行成功,但不能用. ssh164.exp的,這種調用的解釋器是bash)

Expect-自動化互動

Expect中的指令是最重要的部分了,指令的使用文法如下:

指令 [選項] 參數

5.1 spawn

Spawn指令是expect的初始指令,它用于啟動一個程序,之後所有expect操作都在這個程序中進行,如果沒有spawn語句,整個expect就無法執行了,spawn使用方法如下:

在spawn指令後面,直接加上要啟動的程序,指令等資訊,除此之外,spawn還支援其它選項如:

-open 啟動檔案程序

-ignore忽略某些信号

使用方法:

Expect 表達式 動作 表達式 動作 ....

Expect指令用于等候一個相比對内容的輸出,一旦比對上就執行expect後面的動作或指令,這個指令接受幾個特有的參數,用的最多的就是-re,表示使用正規表達式的方式比對,使用起來就是這樣:

spawn ssh [email protected]

expect “password:” { send “123456\r”}   (後邊是\r還是\n有待測試,貌似都可以,隻要加特殊字元就行)

從上面的例子可以看出,expect是依附與spawn指令的,當執行ssh指令後,expect就比對指令執行後的關鍵字:password:,如果比對到關鍵字就會執行後面包含在{}括号中的send或者exp_send動作,比對以及動作可以放在二行,這樣就不需要使用{}括号了,就像下面這樣,實際完成的功能與上面是一樣的:

expect “password:”

send “123456\r”(後邊是\r還是\n有待測試,貌似都可以)

expect指令還有一種用法,它可以在一個expect比對中多次比對關鍵字,并給出處理動作,隻需要将關鍵字放在一個大括号中就可以了,當然還要有exp_continue.

expect {

“yes/no”{ exp_send “yes\r”;exp_continue }

“*password:” { exp_send “123456\r”}

}表示進行多次比對,當比對到第一次,還要進行第進行比對時需要用到exp_continue

5.3 exp_send和send

在上面的介紹中,我們已經看到了exp_send指令的使用,exp_send指令是expect中的動作指令,它還有一個可以完成同樣工作的同胞:send;exp_send指令可以發送一些特殊符号,我們看到的\r(回車),還有一些其它的比如:\n(換行),\t(制表符)等等,這些都是tcl中的特殊符号相同

}

5.4 exp_continue

這個指令一般用在動作中,它被使用的條件比較苛刻,看看下面的例子:

#!/usr/bin/expect

spawn ssh [email protected] /sbin/ifconfig eth0

set timeout 60

        -timeout 5        (設定逾時時間,意思是在指定時間不給出結果,就斷開) 

        "yes/no" { exp_send "yes\r";exp_continue}

        "*password:" { exp_send "happy52121\r" };

        timeout { puts "expect was timeout by test.";return}    (當逾時後,要列印出的内容)

expect eof

exit

在這個例子中,可以發現exp_continue指令的使用方法,首先它要處于一個expect指令中,然後它屬于一種動作指令,完成的工作就是從頭開周遊,也就是說如果沒有這個指令,比對第一個關鍵字以後就會繼續比對第二個關鍵字,但有了這個指令後,比對第一個關鍵字以後,第二次比對仍然從第一個關鍵字開始。

5.5 send_user

send_user指令用來把後面的參數輸出到标準輸出中去,預設的send,exp_send指令都是将參數輸出到程式中的,用起來就像這樣:

send_user “Please input passwd:”

這個語句就可以在标準輸出中列印please input passwd:字元了。相當linux中的echo輸出

exit指令功能很簡單,就是直接退出腳本,但是你可以利用這個指令對腳本做一些掃尾工作,比如下面這樣:

exit -onexit {

exec rm $tmpfile(删除臨時檔案)

send_user “Good bye\n” (說再見,好玩)

Expect-自動化互動
Expect-自動化互動

6.Expect變量

expect中有很多有用的變量,它們的使用方法與TCL語言中的變量相同,比如:

set變量名變量值   #設定變量的方法

puts $變量名#讀取變量的方法

例:接收指令行的參數作為自定義變量

Expect-自動化互動

expect中的特殊關鍵字用于比對過程,代表某些特殊含義或狀态,一般用于expect族中指令中而不能在外面單獨使用,也可以了解為事件,使用上類似于:

expect eof {}

eof(end of file)關鍵字用于比對結束符,比如檔案的結束符,FTP傳輸停止等情況,在這個關鍵字後跟上動作來做進一步控制,特别是ftp互動操作方面,它的作用很大。用一個例子來看看:

spawn ftp [email protected]

“password:” {exp_send “who I’M I”}

eof {ftp connect close}

interact {}

timeout是expect中的一個重要變量,它是一個全局性的時間控制開關,你可以通過為這個變量指派來規定整個expect操作的時間,注意這個變量是服務與expect全局的,它不會糾纏于某一條指令,即使指令沒有任何錯誤,到時間仍然會激活這個變量,但這個時間到達以後除了激活一個開關之外不會做其它的事情,如何處理腳本編寫人員的事情,看看它的實際使用方法:

spawn ssh [email protected]

expect “password:” {send “word\r”}

expect timeout {puts “Expect was timeout”;return}

上面的進行中,首先将timeout變量設定為60秒,當出現問題的時候程式可能會停止下來,隻要到60秒就會激活下面的的timeout動作,這裡我列印一個資訊并且停止了腳本的運作------你可以做更多其它的事情,看自己的意思。

在另一種expect格式中,我們還有一種設定timeout變量的方法,看看下面的例子“

-timeout 60

-re “password:” {exp_send “word\r”}

-re “TopsecOS#” { }

timeout {puts “Expect was timeout”;return}

在expect指令中間加上一個小橫杠,也可以設定timeout變量

timeout變量中,設定為0表示立即逾時,-1則表示永不逾時。

8.生産場景Expect實戰

a.把檔案傳遞到某台主機的某個目錄下,要向腳本傳遞3個參數

if {$argc!=3} {//判斷指令行是否給到3個參數

        send_user "Usage:expect need three arguments lisk thks:file host dir\n"

        exit

set srcname [lindex $argv 0]//取到指令行的第1個參數,并傳遞給變量

set hostname [lindex $argv 1]//取到指令行的第2個參數,并傳遞給變量

set destname [lindex $argv 2]//取到指令行的第3個參數,并傳遞給變量

set password "123456"

spawn scp $srcname root@$hostname:$destname

        -timeout 2

        "yes/no" {send "yes\r";exp_continue}

        "*password:" {send "happy52121\r"}

        timeout {puts "expect connect failure,please contact admin.";return}

        send_user "Jobs has finished,Goodbye.\n"

Expect-自動化互動
Expect-自動化互動

b.使用expect實作批量分發/etc/hosts檔案

在上面例子的基礎上做一些修改,使其可以實作批量分發檔案

#vim scp.sh

#!/bin/bash

iplist=(//把想要操作的IP,定義成一個數組,當然也可以單獨寫到一個檔案中,調用時用`cat iplist`即可

        192.168.50.198

        192.168.50.164

        192.168.50.165

)

for ip in ${iplist[*]}//${iplist[*]}引用數組中的每一個元素

do

expect scp.exp /etc/fstab $ip /tmp

done

Expect-自動化互動

    #. scp.sh//可以看到定義的幾台IP中,複制操作全部執行成功

Expect-自動化互動

再做一些修改使其更專業一點:通過調用/etc/init.d/functions

#vim scp.sh (///bin/ture,表示OK,/bin/false表示FAILED,在開機啟動的時候的你可以看到很多選項後都有)

Expect-自動化互動

#. scp.sh   //這樣看是不是要專業很多呢

Expect-自動化互動

  不過這樣做會有一個問題,因為我在scp.exp檔案中對連接配接逾時的情況做過處理,這樣造成的結果就是不存的IP 也會執行成功(我現在添加一個并不存在的IP192.168.50.256,果看結果也是OK

Expect-自動化互動

是以此時就需要在scp.exp中,把連接配接逾時的情況不做處理,這樣在執行scp.sh時就會傳回值為1

把逾時處理的情況注釋掉,可以看到那個不存的IP處理失敗

Expect-自動化互動
Expect-自動化互動

繼續閱讀