Contents

expect 和 yes 自動化工具

最近在整理 Linux 自動化工具時,又看到 yes 和 expect 這兩個老牌工具。它們都可以處理「本來要人工輸入」的場景,但其實定位差很多。早期如果只看名字,很容易把它們都當成自動化萬用工具,實際上適用情境完全不同。

這篇用工程師比較容易判斷的方式來整理:什麼時候用 yes,什麼時候用 expect,以及什麼情況乾脆直接改用 Ansible 比較實際。

yes 是做什麼的

yes 很單純,它就是一直輸出同一個字串,預設是 y。

常見用途是拿來回覆那種一直問你「Are you sure?」的互動式指令。

例如:

1
2
yes | rm -r large_directory
yes | fsck /dev/foo

它的特性很明確:

  1. 只適合重複回答同一種內容。
  2. 不理解提示內容。
  3. 不會判斷上下文。

所以只要互動流程稍微複雜一點,yes 就不夠用了。

expect 是做什麼的

expect 比較像是「可以觀察互動式程式輸出,再決定要輸入什麼」的工具。它適合處理多階段提示,例如:

  1. SSH 第一次連線確認指紋。
  2. 要輸入帳號。
  3. 要輸入密碼。
  4. 登入後還要再執行幾個命令。

這種情境就不是一直送 y 可以解決的。

expect

簡單範例長這樣:

1
2
3
4
spawn ssh user@example.com
expect "password:"
send "your-password\r"
interact

expect 的核心概念就是:看到什麼字串,就送出什麼回應。

兩者差在哪裡

最簡單的區分方式:

  1. yes 只會一直回答。
  2. expect 會看畫面內容再回答。

如果用表達方式來說:

  1. yes 適合單一、固定、可預期的輸入。
  2. expect 適合多步驟、互動式、依提示變化的流程。

實務上要注意什麼

1. 不要把密碼硬寫進腳本當成常態

expect 很方便,但如果你把正式環境密碼直接寫死在腳本裡,風險很高。這種工具比較適合短期維運、內網工具或過渡期方案。

2. 能改成非互動式就改

很多工具其實都有非互動參數,例如 -y、–force、設定檔、環境變數、SSH key 等。能不用模擬互動,就盡量不用。

3. 超過一定複雜度就不要硬撐

如果你開始要處理多台主機、部署流程、變數管理、失敗重試,那就已經不是 yes 或 expect 的主戰場了。

那為什麼最後常常還是會用 Ansible

這也是我後來的想法。yes 和 expect 很適合快速解決單點問題,但如果要把維運流程做得可維護、可重複、可版本控制,還是 Ansible 這類工具比較完整。

小結

yes 和 expect 都是很好用的自動化小工具,但適用層級不同:

  1. 一直回答同一個東西,用 yes。
  2. 要依提示做互動回應,用 expect。
  3. 要做成正式維運流程,優先考慮 Ansible 或其他自動化工具。

把這三層分清楚,之後遇到互動式指令時,會比較知道該選哪一種工具。