bashumerate:可程式化的 Bash 迭代器

bashumerate:可程式化的 Bash 迭代器

bashumerate 以統一語法簡化 Shell 迭代

bashumerate 是一個可程式化的 Shell 迭代器,取代了 for 迴圈、find -execxargs 各自不同的語法,提供單一且一致的介面。透過 {} 佔位符與統一的指令結構,使用者可以在不必切換不同工具旗標或處理引用怪癖的情況下,對多種來源類型──檔案、行、範圍與清單──進行迭代。

核心功能與來源類型

工具使用一致的模式:enumerate [source_flag] [source] -- [command]。在指令中使用 {} 佔位符來代表目前正在迭代的項目。

支援的來源

旗標 來源 範例
-f 檔案 enumerate -f '*.sh' -- 'wc -l {}'
-l enumerate -l /etc/hosts -- 'echo {}'
-r 範圍 enumerate -r 1 10 -- 'printf "n=%d\n" {}'
-L 清單 enumerate -L a b c -- 'echo item: {}'

主要特性

  • 模板模式:以單引號包住的指令會被視為 Shell 模板,允許使用複雜的管道,例如 enumerate -f '*' -- 'cat {} | head -5'
  • 過濾:內建的 --include--exclude 旗標可對來源項目進行 glob 模式過濾。
  • NUL 安全:提供 -0 旗標以支援 NUL 分隔的輸出,確保檔名含空格或特殊字元時不會中斷迭代。
  • 可擴充性:使用者只要在 lib/enumerators/ 內放入腳本,即可新增自訂來源。任何以 enumerate_source_<name> 命名的函式都會自動成為有效的來源指令(例如 enumerate docker -- 'docker restart {}')。

技術實作

bashumerate 以約 140 行 Bash 程式碼實作。內部將來源視為 NUL 分隔的串流,以確保在特殊字元下的安全性。{} 佔位符在 Shell 層面直接取代,避免使用 sedeval 之類的技巧進行基本置換。

社群批評與替代方案

雖然 bashumerate 旨在簡化 Shell 體驗,但 Hacker News 社群中的資深 Unix 使用者提出了多項技術疑慮,並指出已有的替代方案。

技術疑慮

批評者認為此工具會引入新語法需要學習,同時可能帶來安全或穩定性風險。具體指出:

  • 引用與跳脫:將指令作為單一字串傳遞可能導致複雜的跳脫問題,尤其當迭代項目包含不安全字元時。
  • 子殼層開銷:因為它是獨立工具,總是以子殼層執行,較原生 Bash 迴圈可能有效能影響。
  • 冗餘:bashumerate 提供的許多功能已可透過標準工具達成。例如,原文中提到的「檔名含空格」問題在標準 Unix 中已可透過 NUL 結束解決:

find . -name '*.log' -print0 | xargs --null rm

推薦的替代方案

對於需要更強大或功能更豐富的迭代與平行化需求,社群建議:

  • GNU Parallel:功能強大的平行執行工具,提供 --dry-run 旗標以確保安全。
  • 原生 Bash 迴圈:使用 while read 迴圈可取得最高控制權且不依賴外部工具。
  • 現代 Shell:部分使用者建議改用 PowerShellNushell,這類 Shell 將資料視為物件而非純文字串流,從根本上解決 bashumerate 所針對的迭代問題。

安裝

bashumerate 可透過 basher 管理員安裝,或直接 clone 倉庫後建立符號連結:

git clone https://github.com/wallach-game/bashumerate.git
ln -s "$PWD/bashumerate/bin/enumerate" ~/.local/bin/

Sources