Expect使用小記


By francis_hao    May 31,2017

 

本文翻譯了部分Expect的man手冊,只選取了個人常用的功能,因此並不完善。

 

Expect是一個可以和交互式程序對話的程序

概述

介紹

通過腳本,Expect可以知道應該從對話程序中期望得到什么,和應該回應什么。它支持多分支結構,並且用戶可以在需要的時候取得控制權,並在之后將控制權交還給腳本。

Expect也可以被直接用在c或c++中,詳見libexpect(3)。

Expect可以做的事情:telnet、ftp、ssh和scp等等(如果不在意用戶名和密碼信息)

 

用法

Expect從cmdfile(-f選項指定)中讀取一系列的命令去執行。但一般更常用的方式是將文件作為可執行腳本,在文件第一行添加如下類似的標識,以告知shell通過Expect解析本文件。

#!/usr/bin/expect

 

選項

說明

-c

可執行命令的前置符,其后的命令應該被引起來,該選項可以使用多次,每個-c可以跟多個以分號分隔的命令。命令按照出現的順序執行,例如:

expect -c "puts first\n; puts second" -c "puts three"

-d

輸出一些診斷信息,命令執行時的內部動作。當你寫的腳本和預期不符時,可用此項來調試腳本

-D

交互式的調試器,類似gdb。適合專業人士使用

-f

指定Expect讀取的文件,如果文件是-,則表示是從標准輸入讀取。該選項會將文件一次性全部讀入內存,該選項是可選的

-b

類似-f選項,只是每次只讀取一行

-i

以交互的方式運行expect,等效直接敲expect

--

可以用來界定選項的結束,此項可以用在當你想傳遞一個類似選項的參數時,防止Expect誤認為是選項

-N/-n

如果$exp_library/expect.rc和~/.expect.rc存在,Expect會分別自動讀取,若要阻止此過程則需要分別指定-N和-n。此項一般用不上。

-v

輸出版本號並退出

可選項args的內容以列表的形式被保存在argv中,argc被初始化為argv的長度(個數),argv0保存腳本的名字。

 

 

命令

Expect使用Tcl的語法,又進行了一些擴展,比如spawn、send、expect和interact等。常用的擴展命令如下,按常用度排序

最好的介紹Expect和Tcl的資料是《Exploring Expect》這本書。本man手冊雖然包含示例但十分有限,畢竟man手冊主要作為參考資料。

在本文中Expect指Expect程序,expect指Expect程序中的expect命令。

 

spawn

spawn [args] program [args]

創建一個新的進程運行program [args]。program的標准輸入、標准輸出和標准錯誤都連接到Expect,這樣程序就可以被Expect讀寫了。當Expect執行close命令或者進程關閉了任何文件標識符時,連接會斷開。

當以spawn啟動一個進程時,進程描述符被賦給變量spawn_id,它表示了當前進程,spawn_id可被讀寫,以實現任務控制。

正常情況下,spawn只花費很少的時間,如果spawn耗費了大量的時間,可能是由於pty的問題,此時可以通過-d選項顯示執行過程。

選項

說明

-noecho

默認情況下,spawn會回顯命令名和參數。此選項可以取消回顯。

-ignore

指定在spawned process種要忽略的信號。

 

expect

expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]

等待,直到模式patn匹配到spawn打開的進程的輸出,超過指定的時間,或遇到EOF。

如果模式關鍵字是eof,那么對應的執行體是處理遇到文件結尾的

如果模式關鍵字是timeout,那么對應的執行體是處理超時的,如果沒有指明timeout,則默認不會做任何動作。默認的超時時間是10秒,但是可以通過如下命令重設

set timeout 30

如果設置為-1,則意味着無限等待。

如果模式關鍵字是default,那么對應的執行體會處理超時或文件結尾。

每次新的輸出到達時,會按順序比較每個模式,如果模式匹配到了,那么對應的執行體會被執行。如果有多個模式匹配,只執行第一個出現的。

下面的例子,看起來像一個可以成功登陸的腳本片段。

expect {
    "yes/no"        {send "yes\r";exp_continue}
    "password:"    {send "$passwd\r"}
    default        {exit}
}

字串中可以使用^匹配起始串,用$匹配結尾串。

如果模式關鍵詞是null,那么僅當匹配到一個單個ascii字符"0"時才會執行后面的執行體。沒有可用的辦法來匹配0字節數據,不論是通過全匹配還是正則匹配。

在獲得匹配后,程序的所有輸出字串,截至匹配字串,被保存在變量expect_out(buffer)中,多至九個匹配子串分別被保存在變量expect_out(1,string)至expect_out(9,string)中。

選項

說明

-gl

保護以"-"開始的模式不被認為是選項

-re

正則表達式,在單項前面指定

-ex

匹配確切的字串,不對*、^和$等特殊字符進行翻譯

-nocase

不區分大小寫

-timeout

設置當前expect的超時時間,而不是使用變量timeout的時間

 

 

exp_continue

exp_continue [-continue_timer]

允許expect繼續執行自身而不是往下執行,默認情況下,exp_continue會重置timeout,如果不想重置timeout,使用-continue_timer選項。

 

expect_user

expect_user [expect_args]

類似expect,不過是從標准輸入讀取字符,行必須以回車結尾,以使expect能識別它們。

 

send

send [-flags] string

發送string到當前進程,例如:

send "hello world\r"

就是發送h e l l o <blank> w o r l d <return>到當前進程,

字符會立即被發送,盡管那些行緩沖的程序只會在有回車鍵時才讀取,回車鍵用'\r'表示。因此,下面的示例和上面示例等同。

send "hello "
send "world\r"

 

選項

說明

--

其后的參數被強制解釋成字串,而不是選項。

-i

選項說明字串發送給spawn_id。

-s\-h

慢的輸入\類人的輸入方式,可以提供輸入的間隔設置。具體參見man手冊

   

 

send_error

send_error [-flags] string

類似send,不過輸出發送到標准錯誤,而不是當前進程

 

send_log

send_log [--] string

類似send,不過string只發送到log文件。(see log_file)

 

send_tty

send_tty [-flags] string

類似send,不過輸出發送到/dev/tty而不是當前進程。

 

send_user

send_user [-flags] string

類似send,不過輸出發送到標准輸出,而不是當前進程。

 

 

interact

interact [string1 body1] ... [stringn [bodyn]]

將當前進程的控制權交付給用戶。

string-body對可以作為參數,以使當有string輸入時,執行body。下面的示例看上去是一個可運行片段。

interact {
    "abc" {send_user "you typed abc\n"}
    "123" {send_user "you typed 123\n"}
}

輸入的字符會按string列出的順序進行匹配,當有部分匹配時,當前輸入的字符不會被發送到當前進程,只有當后續輸入的字符不能使之匹配時才會發送,若匹配則執行body。以上例為例,在輸入"abc"的過程中,進程不會回顯這些字符,如果輸入"abq",則只有在輸入到"q"時,"abq"才會同時被回顯。

選項

說明

-ex

防止以"-"開頭的模式被翻譯成選項

-re

用正則匹配的模式翻譯string,此選項下匹配的子串被保存在變量interact_out中。類似expect的expect_out。

-echo

回顯每一個字符,即使這個字符會被匹配中

   

當模式是eof時,表示遇到文件結尾的行為,默認是"return"。

當模式是timeout時(需指定超時時間),表示在指定時間沒有輸入時的行為,此項沒有默認的超時時間,變量timeout的值在此無效。

當模式是null時,僅當匹配到一個單個ascii字符"0"時才會執行后面的執行體。沒有可用的辦法來匹配0字節數據,不論是通過全匹配和正則匹配。

interact中的return使interact返回到它的調用。而inter_return使interact的調用執行return

 

 

sleep

sleep seconds

腳本進入睡眠模式,睡眠時間單位為秒

 

close

close [-slave] [-onexec 0|1] [-i spawn_id]

關閉連接到當前進程的連接

選項

說明

-i

指定關閉名為spawn_id的進程

-onexec

檢測是否有新打開的進程或進程是否有重疊,若有,

0:保持打開,1:強制關閉

-slave

關閉spawn_id關聯的子進程

 

exit

Expec退出

 

 


本文由 劉英皓 創作,采用 知識共享 署名-非商業性使用-相同方式共享 3.0 中國大陸 許可協議進行許可。歡迎轉載,請注明出處:
轉載自:http://www.cnblogs.com/yinghao1991/p/6926125.html

 

參考

【1】man expect


免責聲明!

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



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