跳轉到

2005:Fish 問世#

事件#

2005 年,Axel Liljencrantz 發表 fish(friendly interactive shell)。fish 是第一個公開宣示「不以 POSIX 相容為念」的現代 shell——它徹底捨棄歷史包袱,只為互動體驗而設計。

新語法與特性及其理論、實用原因#

1. 自動建議(autosuggestion,灰色文字提示歷史命令)#

  • 理論原因:使用者最常重複過去的命令,建議應該「主動出現」而非「被動搜尋」。
  • 實用原因:打幾個字母,歷史命令以灰色出現,按右鍵接受。
  • 彌補缺陷:bash/zsh 需要 Ctrl-R 搜尋或外掛(zsh-autosuggestions 是 2010 年代才出現的外掛)。

2. 語法高亮(syntax highlighting)#

  • 理論原因:即時回饋(immediate feedback)——錯誤在按下 Enter 前就該被看見。
  • 實用原因:命令存在與否、引號是否閉合,即時以顏色顯示。
  • 彌補缺陷:傳統 shell 的錯誤要等執行後才發現。

3. 開箱即用的補全(不需設定)#

  • 理論原因:「友善」的定義——功能應該預設開啟,而非靠設定檔堆砌。
  • 實用原因:安裝即用,與 zsh 的「需先配置 oh-my-zsh」相反。
  • 彌補缺陷:zsh 補全強大但設定門檻高。

4. 全新腳本語法(set var value、function ... end、if ... end)#

  • 理論原因:POSIX 語法的 fi、esac、$var 引號陷阱,是為了 1970 年代的實作限制而生的歷史包袱;fish 選擇語法一致性勝過相容性。
  • 實用原因:set 是普通命令、變數內建 list 型別(自動處理空格)。
  • 彌補缺陷:bash 中「含空格的變數要加引號」是五十年來最常見的腳本 bug 來源;fish 的 list 型別從根本消除這一類錯誤。

5. 不相容 POSIX 的代價與收益#

  • 代價:不能直接跑既有腳本。
  • 收益:fish 的定位是「互動 shell」,腳本仍用 bash/POSIX——「互動用 fish、腳本用 bash」成為新分工。
  • 彌補缺陷:證明了 shell 可以脫離 POSIX 包袱重新設計,啟發了之後的 nushell、elvish、oil。

程式範例:Fish 的語法#

# 1. 自動建議:打幾個字母,歷史命令以灰色出現,按右鍵接受
# (bash/zsh 要靠 Ctrl-R 或 2010 年代的外掛)
# 2. 語法高亮:錯誤即時可見
# 不存在的命令顯示紅色、存在的顯示藍色——按下 Enter 前就看到
# 3. 全新腳本語法:一致性勝過相容性
set files a.txt "my b.txt" c.txt    # set 是普通命令,不需 = 
echo $files[2]                       # my b.txt(list 型別自動處理空格)
# 4. 條件與迴圈:end 收尾,引號陷阱消失
if test -f config.txt
    echo "存在"
else
    echo "不存在"
end

for f in *.c
    echo "編譯 $f"
end
# 5. 函數
function backup
    cp $argv /backup/        # $argv 自動是 list
end
backup notes.txt
# 對比:bash 的經典 bug(fish 從根本消除)
# bash:變數含空格不加引號就會分裂成多個參數
# f="my file.txt"; cp $f /backup   # 錯!cp 收到 my 和 file.txt 兩個參數
# fish:list 型別,變數就是值,永不分裂

歷史意義#

fish 把「互動體驗」推向極致,其自動建議與語法高亮後來被幾乎所有現代 shell 與終端機(含 2020 年代的 AI shell)吸收。它是「放棄相容性換取體驗」路線的代表。

彌補了什麼缺陷#

彌補了傳統 shell「互動體驗落後現代編輯器一個時代」的缺陷:沒有建議、沒有高亮、錯誤回饋太晚。

相關條目#