Linux-expect命令詳解
2015年04月16日 10:38:57 jacky0922 閱讀數 11406
Expect (主頁http://expect.nist.gov/) 是用於提供自動交互的工具。比如你要用ssh或者 telnet登錄服務器的時候,命令行下提示需要輸入用戶和密碼等。如果叫你用shell腳本寫自動登錄腳本的話是不是有點困難呢? 你會說在shell中執行ssh命令的話,他會一直停在那裏等你密碼啊,這個要手工來做才行吧?
Expect就是爲處理這類情況而設計的工具,簡單來說它可以控制、處理輸入,輸出流,然後提供自動填寫數據等需要用戶交互式輸入的數據的地方實現自動化處理。Expect就是爲了處理“自動交互”的工具。
Expect 支持自定義的腳本,所以你通過編寫自定義腳本就可以實現你想要的自動填寫數據功能了
- expect & tcl
Expect採用的是一種叫做Tcl (Tool Command Language )的腳本語言,所以你至少要學習一下TCL它的語法。
TCL資料
TCL網站
Tcl/Tk 8.5 Manual: http://www.tcl.tk/man/tcl8.5/ & http://tmml.sourceforge.net/doc/tcl/index.html
Tcl Tutorial: http://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html
Tcl syntax help: http://wiki.tcl.tk/1019
Learning Tcl: http://wiki.tcl.tk/20789
上面幾個網站都屬於Tclers Wiki http://wiki.tcl.tk/ 下面的分支來的。
TCL書籍
還有一本書《Practical Programming in Tcl and Tk》
http://www.beedub.com/book/
亞馬遜鏈接: Tcl/Tk入門經典(第2版)
expect現在也有Perl和Python的版本
Python expect: python expect模塊pexpect簡單應用
Perl版本:Expect也有人移植到perl 等語言裏面,叫做 Expect.pm ,使用起來也很方便,不過那個應該不是主流
- expect 命令
要使用EXpect,你還要熟練 掌握Expect中定義的命令
如 expect , spawn,send ,wait等等。
這個的參考主要有:
Expect手冊 ? Manpage of Expect http://www.tcl.tk/man/expect5.31/expect.1.html
還有一個網站 也是expect命令介紹 http://www.cotse.com/dlf/man/expect/index.htm
Expect中最關鍵的四個命令是send,expect,spawn,interact。
send:用於向進程發送字符串
expect:從進程接收字符串
spawn:啓動新的進程
interact:允許用戶交互
- send命令
send命令接收一個字符串參數,並將該參數發送到進程。
expect1.1> send "hello world\n"
hello world
- expect命令
(1)基礎知識
expect命令和send命令正好相反,expect通常是用來等待一個進程的反饋。expect可以接收一個字符串參數,也可以接收正則表達式參數。和上文的send命令結合,現在我們可以看一個最簡單的交互式的例子:
expect "hi\n"
send "hello there!\n"
這兩行代碼的意思是:從標準輸入中等到hi和換行鍵後,向標準輸出輸出hello there。
tips: $expect_out(buffer)存儲了所有對expect的輸入,<$expect_out(0,string)>存儲了匹配到expect參數的輸入。
比如如下程序:
expect "hi\n"
send "you typed <$expect_out(buffer)>"
send "but I only expected <$expect_out(0,string)>"
當在標準輸入中輸入
test
hi
是,運行結果如下
you typed: test
hi
I only expect: hi
(2)模式-動作
expect最常用的語法是來自tcl語言的模式-動作。這種語法極其靈活,下面我們就各種語法分別說明。
單一分支模式語法:
expect "hi" {send "You said hi"}
匹配到hi後,會輸出"you said hi"
多分支模式語法:
expect "hi" { send "You said hi\n" } \
"hello" { send "Hello yourself\n" } \
"bye" { send "That was unexpected\n" }
匹配到hi,hello,bye任意一個字符串時,執行相應的輸出。等同於如下寫法:
expect {
"hi" { send "You said hi\n"}
"hello" { send "Hello yourself\n"}
"bye" { send "That was unexpected\n"}
}
- spawn命令
上文的所有demo都是和標準輸入輸出進行交互,但是我們跟希望他可以和某一個進程進行交互。spawm命令就是用來啓動新的進程的。spawn後的send和expect命令都是和spawn打開的進程進行交互的。結合上文的send和expect命令我們可以看一下更復雜的程序段了。
set timeout -1
spawn ftp ftp.test.com //打開新的進程,該進程用戶連接遠程ftp服務器
expect "Name" //進程返回Name時
send "user\r" //向進程輸入anonymous\r
expect "Password:" //進程返回Password:時
send "123456\r" //向進程輸入[email protected]\r
expect "ftp> " //進程返回ftp>時
send "binary\r" //向進程輸入binary\r
expect "ftp> " //進程返回ftp>時
send "get test.tar.gz\r" //向進程輸入get test.tar.gz\r
這段代碼的作用是登錄到ftp服務器ftp ftp.uu.net上,並以二進制的方式下載服務器上的文件test.tar.gz。程序中有詳細的註釋。
4.interact
到現在爲止,我們已經可以結合spawn、expect、send自動化的完成很多任務了。但是,如何讓人在適當的時候干預這個過程了。比如下載完ftp文件時,仍然可以停留在ftp命令行狀態,以便手動的執行後續命令。interact可以達到這些目的。下面的demo在自動登錄ftp後,允許用戶交互。
spawn ftp ftp.test.com
expect "Name"
send "user\r"
expect "Password:"
send "123456\r"