Expect被設計成專門針和交互式程序的交互。一個Expect程序員可以寫一個腳本來描述程序和用戶的對話。
接着Expect 程序可以非交互的運行“交互式”的程序。寫交互式程序的腳本和寫非交互式程序的腳本一樣簡單。
Expect還可以用於對對 話的一部分進行自動化,因爲程序的控制可以在鍵盤和腳本之間進行切換。
spawn命令激活一個Unix程序來進行交互式的運行。 send命令向進程發送字符串。expect命令等待進程的某些字符串。
expect支持正規表達式並能同時等待多個字符串,並對 每一個字符串執行不同的操作。expect還能理解一些特殊情況,
如超時和遇到文件尾。
expect patlist1 action1 patlist2 action2.....
該命令一直等到當前進程的輸出和以上的某一個模式相匹配,或者等
到時間超過一個特定的時間長度, 或者等到遇到了文件的結束爲止。
如果最後一個action是空的,就可以省略它。
每一個patlist都由一個模式或者模式的表(lists)組成。
如果有一個模式匹配成功,相應的action就被執行。執 行的結果從expect返回。
被精確匹配的字符串(或者當超時發生時,已經讀取但未進行匹配的字符串)被存貯在變量expect_match裏面。
如 果patlist是eof或者timeout,則發生文件結束或者超時時才執行相應的action.
一般超時的時值是10秒,但可以用類似 "set timeout 30"之類的命令把超時時值設定爲30秒。
模式是通常的C Shell風格的正規表達式。模式必須匹配當前進程的從上一個expect或者interact開始的所有輸 出(所以統配符*使用的非常)的普遍。但是,
一旦輸出超過2000個字節,前面的字符就會被忘記,這可以通過設定 match_max的值來改變。
字符可以使用反斜槓來單獨的引用,反斜槓也被用於對語句的延續,如果不加反斜槓的話,語句到一行的結尾處就結 束了。分號可以用於在一行中分割 多個語句。
啓動方式
#!/usr/bin/expect
命令行方式
expect -c "set timeout 20;spawn foo;expect"
到了文件結束符(EOF),該程序就會停下來,然後expect返回。如果是遇到了超時的情況,expect就返回。在這兩
中情況裏面,都隱式的殺死了當前進程。
命令
exec sleep 4 "exec" 執行 命令
spawn 開始expect 過程
set 設置變量值
set tt 3
expect 開始模式處理
send 響應
[] 取結果 如[index $argv 2] ,命令序列的結果 [ls]
{}命令組 abort 異常中斷
exit n 返回
break ?
interact + 返回用戶控制,"+"控制用戶的控制行爲
close 關閉
wait 等待進程退出
expect_user 等待實際用戶輸入
send_user 向用戶輸出
send_error 向標準錯誤終端輸出
內置變量
使用變量方式 a=${b} a= $b
timeout
eof
expect_match 被精確匹配或者在超時前沒匹配的串
match_max expect_match的最大長度
argv 輸入參數表,$argv[0]爲程序本身名字,用 [index $argv n]引用第n個值
spawn_id 當前捕獲對象的進程 id,更換該id爲當前子進程的其他值,可實現對輸出的捕獲
邏輯控制
循環語句
for{} {1} {}{do something}
分支語句
set x [ ... ]#依次取a,b的一個可以是 select $a $b
case $x in $a {}
case $x in $b {}
多個spawn 最後一個進程輸出被作爲expect ,send的對象
if $a 邏輯值
例子 1
單獨事務處理
for {} {1} {}{
expect \
eof break \
"*UNREF FILE*CLEAR?" {send "y "} \
"*BAD INODE*FIX?" {send "y "} \
"*?" {interact +} \
}
多進程切換
spawn chess ;# start player one
set id1 $spawn_id
expect "Chess "
send "first " ;# force it to go first
read_move
set id2 $spawn_id
expect "Chess "
for {} {1} {}{
send_move
read_move
set spawn_id $id1
send_move
read_move
set spawn_id $id2
}
例子3
多進程切換
spawn tip /dev/tty17 ;# open connection to
set tty $spawn_id ;# tty to be spoofed
set login $spawn_id
for {} {1} {} {
set ready [select $tty $login]
case $login in $ready {
set spawn_id $login
expect
{"*password*" "*login*"}{
send_user $expect_match
set log 1
}
"*" ;# ignore everything else
set spawn_id $tty;
send $expect_match
}
case $tty in $ready {
set spawn_id $tty
expect "* *"{
if $log {
send_user $expect_match
set log 0
}
}
"*" {
send_user $expect_match
}
set spawn_id $login;
send $expect_match
}
}