用expect實現shell指令碼的自動互動
對於複雜的互動,甚至結合螢幕輸出的不同進行不同的處理,都是非常有效。
而且一般的linux、unix都有。非常易用卻又很強大
spawn telnet XXX
expect “username”
send “xxxxx/r”
expect “password”
send “xxxx/r”
expect “last login*”
send “xxx”
…
利用expect實現自動互動 Expect的作者Don Libes在1990年開始編寫Expect時對Expect做有如下定義:
(Expect is a software suite for automating interactive tools。
Expect的官方首頁對它作了如下介紹:
Expect is a tool for automating interactive applications such as telnet,
ftp, passwd, fsck, rlogin, tip, etc. Expect really makes this stuff
trivial. Expect is also useful for testing these same applications. And
by adding Tk, you can also wrap interactive applications in X11 GUIs.
Expect是基於TCL的,作為一個指令碼語言,expect能在無需管理員參與的情況下實現
自動互動(比如passwd,fsck,telnet等),expect也能用於自動化的測試一些應用程式。
expect的文法和shell的文法非常相似,它支援函數調用,有while語句,switch
語句。
1) expect使用spawn調用其他的執行程式,比如
spawn telnet 218.199.20.98 2600
但是在使用的過程中發現spawn不支援管道和重新導向,也就是說對於
ls |more ; mysql -p < update.sql 這樣的命令spawn不能正確解析。
解決的辦法是把這些命令放到一個shell指令碼裡面,在用spawn執行這個shell
指令碼。
2) expect 建立子函數使用proc標誌,也即:
proc functionname { parameter1,parameter2 } {
......
}
調用子函數非常簡單
functionname $param1 $param2
3) expect 使用expect ,send 組合實現自動互動 ,文法如下:
expect {
"login;" { send "$user/n" }
"passwd:" { send "$passwd/n" }
}
使用send的使用後面的內容不顯示給使用者,如要顯示給使用者,應使用send_user
4) 注意點:
1. expect裡面基本是都是使用{} 而不是使用(),比如函數參數輸入外面應用{},
應該是while { } 而不是 while ( ).
2. { 應和其他符合有空格, expect { 正確,expect{ 就會報錯.
3. spawn 不支援管道和重新導向.
5) 下面是實現的mysql資料庫自動更新的expect指令碼:
proc do_console_login {pass} {
set timeout 5
set done 1
while { $done } {
expect {
"password:" {
send "$pass/n"
}
eof {
set done 0
}
}
}
}
if {$argc<1} {
puts stderr "Usage: $argv0 password./n "
exit 1
}
set PASS [lindex $argv 0]
spawn /usr/local/mysql/data/updatemysql
do_console_login $PASS