1990:Zsh 誕生#
事件#
1990 年,普林斯頓大學的 Paul Falstad 寫出了 Zsh 的第一版(名字來自教授 Zhong Shao 的登入帳號 zsh)。zsh 的設計哲學是「集大成」:把 sh、ksh、tcsh 的所有優點收進一個高度可客製化的 shell。
新語法與特性及其理論、實用原因#
1. 極致可編程補全(programmable completion)#
- 理論原因:命令參數有語境,補全系統應是可編程的(每個命令可註冊自己的補全規則)。
- 實用原因:
git <Tab>補子命令、ssh <Tab>補主機名——這是 zsh 最殺手級的功能。 - 彌補缺陷:bash 直到 2000 年代(bash-completion 專案)才有類似能力;tcsh 的補全不可編程狀態機。
- 伏筆:這個特性是 2010 年 Oh My Zsh 生態爆發的技術基礎。
2. 主題化提示符(prompt themes)與右提示符(RPROMPT)#
- 理論原因:提示符是 shell 的「使用者介面」,應可完全客製化。
- 實用原因:右提示符顯示版本控制狀態(git branch)等,左邊保持乾淨。
- 彌補缺陷:bash 提示符只有簡單的
PS1字串。
3. 進階 glob(** 遞迴萬用字元、修飾符 (:r) 等)#
- 理論原因:檔名展開是 shell 的核心運算,應更強大。
- 實用原因:
**/*.c遞迴找所有 C 檔案,不必用find。 - 彌補缺陷:bash 的
*只匹配單層(**直到 bash 4.0/2009 年才補上)。
4. 完全相容 ksh/sh 語法的腳本能力#
- 實用原因:既有腳本零成本遷移。
- 彌補缺陷:csh/tcsh 腳本語法不相容 sh 的分裂。
5. 豐富的選項系統(setopt/unsetopt)#
- 理論原因:不同使用者的行為預期不同,shell 應以選項而非分支實作差異。
- 實用原因:
setopt autocd、setopt share_history等微調。
程式範例:Zsh 的殺手級語法#
# 1. 遞迴 glob:不需 find
ls **/*.c # 所有子目錄的 C 檔案
rm **/*.o # 遞迴刪除目的檔
# 2. 可編程補全:依語境補全
compdef _gnu_generic mytool # 為自訂工具註冊補全
autoload -Uz compinit && compinit # git <Tab> 補子命令、ssh <Tab> 補主機名
# 3. 右提示符與主題化
setopt prompt_subst
RPROMPT='%* # 右邊顯示時間,左邊保持乾淨
# 4. 進階字串與陣列操作
files=(a.txt "my b.txt" c.txt)
print -l $files # list 型別正確處理空格
echo ${(u)files} # u = 去重複
# 5. 選項系統
setopt autocd # 輸入目錄名即 cd
setopt share_history # 多終端共享歷史
setopt correct # 拼字修正
歷史意義#
zsh 長期是「行家之選」,2010 年 Oh My Zsh 問世後大眾化,2019 年成為 macOS 預設 shell。它是「體驗即語言」路線的極致。
彌補了什麼缺陷#
彌補了 bash「補全與客製化貧乏」的交互缺陷,同時保住 ksh/sh 腳本相容性——它證明了兩者可以兼得甚至兼優。