Rubish:彌合 Bash 與 Ruby 之間的鴻溝
數十年來,Unix shell 一直是系統管理與自動化的主要介面。雖然 Bash 是業界標準,但其語法在處理複雜邏輯時會變得繁瑣,導致開發者常在 shell 腳本與更高階語言(如 Python 或 Ruby)之間切換。於是誕生了 Rubish,一個以純 Ruby 編寫的 Unix shell,旨在提供兩者的最佳結合:完整的 Bash 相容性與深入的 Ruby 整合。
Rubish 不僅僅是使用 Ruby 實作的 shell;它是一個混合環境,將 shell 語法解析並編譯成 Ruby 程式碼,然後由 Ruby VM 執行。此架構允許使用者在不修改現有 Bash 腳本的情況下執行它們,同時能夠無縫地將 shell 指令與 Ruby 強大的物件導向功能混合使用。
混合體驗:Bash 相容性與 Ruby 威力的結合
在核心上,Rubish 嚴格遵守 Bash 相容性。此專案旨在支援所有 Bash 功能,將任何不相容的腳本視為錯誤。這確保使用者不必拋棄現有的工具鏈就能嘗試新 shell。
然而,Rubish 的真正價值在於其「超越 Bash 的功能」,讓開發者能突破傳統 shell 的限制:
以 Ruby 為動力的邏輯與迭代
與其與複雜的 shell 條件式糾纏,Rubish 允許在 if、while 與 until 區塊中使用以大括號包住的 Ruby 表達式。Shell 變數會自動綁定為這些表達式內的本地變數:
COUNT=5
if { count.to_i > 3 }
echo 'count is greater than 3'
end
此外,Rubish 引入了 Ruby 迭代器區塊(.each、.map、.select),使得能以 Ruby 集合的優雅方式逐行處理指令輸出:
ls.select { it.end_with?('.rb') }.each { |f| puts f.upcase }
重新定義指令鏈接方式
雖然傳統的管道符號 (|) 仍可使用,Rubish 透過點號表示法引入方法鏈接。只要以括號開啟指令,使用者即可像呼叫 Ruby 方法般串接操作:
# Equivalent to: cat file.txt | grep error
cat(file.txt).grep(/error/)
內嵌 Ruby 評估
對於將 shell 當作 REPL 使用的使用者,Rubish 允許任何以大寫字母開頭的行直接作為 Ruby 程式碼評估。這省去在執行快速計算或查詢 Ruby 標準函式庫時需要特殊跳脫字元的麻煩:
rubish$ Time.now
=> 2025-01-01 12:00:00 +0900
rubish$ Dir.glob('*.rb').sort
=> ["Gemfile", "Rakefile"]
進階 Shell 工程
Rubish 包含多項為現代開發者工作流程設計的高階功能:
- Lazy Loading: 為了解決
rbenv或nvm等工具導致的 shell 啟動緩慢問題,Rubish 提供lazy_load區塊。此區塊將初始化延遲至背景執行緒,確保提示字元即時顯示,同時環境在背景中完成設定。 - Custom Programmatic Prompts: 不使用靜態字串,提示字元可定義為 Ruby 函式,允許在每次提示刷新時以程式方式呈現動態內容(例如目前的 Git 分支)。
- Restricted Mode: 為了安全性,
rubish -r會停用所有 Ruby 整合,只允許使用標準 shell 語法執行不受信任的腳本。 - Zsh Compatibility: 除了 Bash,Rubish 也支援 Zsh 風格的功能,包括
setopt、compinit以及縮寫路徑展開(例如a/c/a<Tab>會展開為完整路徑)。
開發者觀點與取捨
此專案在技術社群中引發了有趣的討論,尤其是關於如此深度整合的取捨問題。
「Vibe-Coding」辯論
一些貢獻者注意到大型語言模型(LLM)在專案開發中的影響。某位評論者 @ciconia 表示擔憂,認為部分程式碼過於「難以穿透」,質疑使用編碼代理是否會導致方法過長或缺乏清晰的介面邊界,進而使得沒有類似工具的人類開發者難以貢獻。
效能與可移植性
與所有以高階語言編寫的 shell 一樣,效能是爭議焦點。雖然有使用者指出 Ruby 比 Python 更快,但也有人質疑 Rubish 與如 Almquist shell 這類極簡 shell 的比較。遠端環境亦是一大實務障礙;正如 @freedomben 所指出的,必須在每台遠端伺服器上安裝 Ruby 執行環境,使得 Rubish 的可移植性不如靜態連結的二進位 shell。
「Shell 中的物件」的吸引力
儘管受到批評,仍有強烈需求採用此方式。來自 PowerShell 的使用者指出,對「Bash 但具備物件」的渴望相當普遍,而能利用 method_missing 動態處理 shell 指令,被視為 Ruby 元程式設計優勢的完美應用。
嵌入 Rubish
Rubish 最強大的特點之一是其公開 API。由於以 Ruby 編寫,它可以嵌入其他 Ruby 程式中,無需 fork+exec 或 JSON 序列化。這使得 IDE 外掛或終端機模擬器(如同伴專案 Echoes)能在同一進程中驅動 Rubish 會話,提供進階的語法突顯與程式化的指令執行控制。