對於追求自動化的 Linux 系統管理員,Expect 是基於 Tcl 語言開發的經典互動式自動化工具,廣泛應用於批次部署、自動化測試、多伺服器同步操作等場景。本文整理自 thegeekstuff.com 技術分享,詳細說明 Expect 腳本的多種執行模式與除錯技巧,助你靈活駕馭自動化流程。
本文假設讀者已具備 Expect 基本語法概念(spawn、expect、send、interact)。初學者建議先閱讀官方 Expect 手冊 或「Hello World」範例。
-c 參數:命令列直接執行單行腳本$ expect -c 'expect "\n" {send "pressed enter\n"}'
pressed enter
等待使用者按 Enter,印出訊息後結束。適合臨時測試或嵌入 Shell 腳本。
-i 參數:互動模式執行$ expect -i arg1 arg2 arg3
expect1.1> set argv
arg1 arg2 arg3
expect1.2>
啟動互動式 Expect 提示符,可手動輸入指令。參數 arg1 arg2 arg3 會被視為 argv 列表,而非腳本檔名。搭配 -c 使用時特別有用。
-d 參數:輸出診斷除錯資訊$ expect -d sample.exp
expect version 5.43.0
argv[0] = expect argv[1] = -d argv[2] = sample.exp
...
expect: does "" (spawn_id exp0) match glob pattern "\n"? no
expect: does "\n" (spawn_id exp0) match glob pattern "\n"? yes
send: sending "pressed enter" to { exp0 pressed enter}
詳細顯示模式比對過程、發送內容、spawn_id 狀態,是除錯複雜腳本的利器。
-D 參數:啟動內建除錯器$ expect -D 1 script.exp
# 或
$ expect -c 'set timeout 10' -D 1 -c 'set a 1'
1: set a 1
dbg1.0>
-D 1 表示立即進入除錯器;-D 0 僅初始化稍後再用。除錯器啟動前的參數會先被處理,啟動後才處理剩餘指令。
-b 參數:逐行讀取執行(邊寫邊跑)$ expect -b
不將整個腳本載入記憶體,而是逐行讀取執行。適合腳本尚未寫完時先測試前段邏輯,避免建立暫存檔。
-- 分隔符:停止解析命令列選項,後續視為腳本參數$ cat print_cmdline_args.exp
#!/usr/bin/expect
puts "argv0 : [lindex $argv 0]"
puts "argv1 : [lindex $argv 1]"
$ expect print_cmdline_args.exp -- -d -c
argv0 : -d
argv1 : -c
若腳本需接收以 - 開頭的參數(如 -d、-c),必須用 -- 分隔,否則會被 Expect 視為自身選項吞掉。
spawn ssh user@host、expect "password:"、send "pwd\r" 實現免互動登入執行指令。Expect 的強項在於「處理互動」。掌握 -c、-i、-d、-D、-b、-- 六大模式,能讓你在開發、除錯、生產部署三階段靈活切換執行方式,大幅提升自動化腳本的開發效率與可維護性。