文章目錄
- 基本使用流程
- 基本方法
-
- spawn
- expect
- send
-
- sendline
- sendcontrol
- 特殊變量
-
- pexpect.EOF
- pexpect.TIMEOUT
Expect 程式主要用于人機對話的模拟,就是那種系統提問,人來回答 yes/no ,或者賬号登入輸入使用者名和密碼等等的情況。因為這種情況特别多而且繁瑣,是以很多語言都有各種自己的實作
pexpect 是 Python 語言的類 Expect 實作。從我的角度來看,它在功能上與 TCL 語言的實作還是有一些差距,比如沒有buffer_full 事件、比如沒有 expect before/after 事件等,但用來做一般的應用還是足夠了
基本使用流程
- 首先用 spawn 來執行一個程式
- 然後用 expect 來等待指定的關鍵字,這個關鍵字是被執行的程式列印到标準輸出上面的
- 最後當發現這個關鍵字以後,根據關鍵字用 send 方法來發送字元串給這個程式
基本方法
spawn
上面 spawn() 中的字元串就是要執行的程式,這裡我們打開一個到 sw-tftp 伺服器的 ftp 連接配接。 spawn() 中的第一個元素就是要執行的指令,除此之外還可以指定一些其他參數
- timeout:逾時時間,預設時長為30s
- maxread:緩存設定,指定一次性試着從指令輸出中讀多少資料。如果設定的數字比較大,那麼從 TTY 中讀取資料的次數就會少一些
- logfile:當給 logfile 參數指定了一個檔案句柄時,所有從标準輸入和标準輸出獲得的内容都會寫入這個檔案中(注意這個寫入是 copy 方式的),如果指定了檔案句柄,那麼每次向程式發送指令(process.send)都會重新整理這個檔案(flush)
expect
當 spawn() 啟動了一個程式并傳回程式控制句柄後,就可以用 expect() 方法來等待指定的關鍵字了。它最後會傳回 0 表示比對到了所需的關鍵字,如果後面的比對關鍵字是一個清單的話,就會傳回一個數字表示比對到了清單中第幾個關鍵字,從 0 開始計算
index = process.expect([
'Permission Denied',
'Terminal type',
'ftp>',
])
if index == 0:
print "Permission denied at host, can't login."
process.kill(0)
elif index == 1:
print "Login ok, set up terminal type…"
process.sendline('vty100')
process.expect("ftp>")
elif index == 2:
print "Login Ok, please send your command"
process.interact()
如果要檢查或者比對 expect.EOF 和 expect.TIMEOUT 這兩種情形,那麼必須将它們放進比對清單裡面去,這樣可以通過檢查傳回的數字來處理它們。如果沒放進清單的話,就會發生 EOF 或者 TIMEOUT 錯誤,程式就會中途停止了
send
send() 作為3個關鍵操作之一,用來向程式發送指定的字元串,它的使用沒什麼特殊的地方
sendline
sendline() 和 send() 唯一的差別就是在發送的字元串後面加上了回車換行符,這也使它們用在了不同的地方
sendcontrol
sendcontrol() 向子程式發送控制字元
特殊變量
pexpect.EOF
EOF 變量使用範圍很廣泛,比如檢查 ssh/ftp/telnet 連接配接是否終止啊,檔案是否已經到達末尾啊。 pexpect 大部分腳本的最後都會檢查 EOF 變量來判斷是不是正常終止和退出,比如下面的代碼
pexpect.TIMEOUT
TIMEOUT 變量用來比對逾時的情況,預設情況下 expect 的逾時時間是 60 秒,如果超過 60 秒還沒有發現期待的關鍵字
其餘更多的用法可以參考下面這邊文章,非常詳細
https://www.jianshu.com/p/cfd163200d12