2009:Bash 4.0——關聯陣列與萬用字元強化#
事件#
2009 年 2 月,Bash 4.0 問世(由 Chet Ramey 維護)。這是 bash 語法表達力最大的一次擴充,補上了資料結構與檔名展開的兩大長期缺口。
新語法與特性及其理論、實用原因#
1. 關聯陣列(declare -A map)#
- 理論原因:鍵值對(key-value pair)是最常用的資料抽象,ksh93 早在 1993 年就有。
- 實用原因:
map[key]=value直接做查找表,不需靠「字串拼接 + grep」模擬。 - 彌補缺陷:bash 2.0 只有索引陣列,鍵值查找必須用兩個平行陣列或外部程式(awk)。
2. 遞迴萬用字元 **(需 shopt -s globstar)#
- 理論原因:檔名展開是 shell 的核心運算,zsh(1990)早已支援遞迴 glob。
- 實用原因:
ls **/*.c遞迴列出所有 C 檔,不需find . -name。 - 彌補缺陷:bash 的
*只匹配單層目錄,遞迴必須依賴外部find。
3. &>>、|& 等重導向簡寫#
- 實用原因:
cmd &>> file同時重導向 stdout/stderr 並附加;|&把 stderr 也送進管線。 - 彌補缺陷:
cmd >> file 2>&1語序易錯(2>&1放錯位置是經典 bug);ksh 的 coprocess 語法於此跟進。
4. coproc 雙向管線#
- 理論原因:管線只有單向流(1973 年的設計),長駐行程無法互動。
- 實用原因:腳本可與背景行程雙向溝通(如互動式資料庫)。
- 彌補缺陷:ksh93 早在 1988 年就有
|&,bash 補上。
5. ${var,,}、${var^^} 大小寫轉換與 declare -l/-u#
- 實用原因:大小寫轉換不需 fork
tr。
程式範例:Bash 4.0 的新語法#
# 1. 關聯陣列:鍵值查找表(ksh93 早在 1993 就有)
declare -A ver
ver[bash]=3.2
ver[zsh]=5.9
echo "${ver[bash]}" # 3.2
echo "${!ver[@]}" # bash zsh(所有鍵)
# 對比:以前要靠兩個平行陣列或 awk 模擬
# 2. 遞迴 glob(globstar)
shopt -s globstar
ls **/*.c # 遞迴列出所有 C 檔——不需 find
rm **/*.o
# 對比:以前的寫法
# find . -name '*.c' -exec ls {} \;
# 3. 重導向簡寫
prog &>> log.txt # stdout+stderr 附加到檔案
# 對比:cmd >> log.txt 2>&1——語序易錯(2>&1 放錯位置是經典 bug)
prog |& grep ERROR # stderr 也送進管線
# 對比:prog 2>&1 | grep ERROR
# 4. coproc:雙向管線
coproc SQLITE { sqlite3 test.db; }
echo "SELECT 1;" >&"${SQLITE[1]}" # 送命令
read line <&"${SQLITE[0]}" # 讀結果
# 5. 大小寫轉換:不需 fork tr
s="Hello World"
echo "${s,,}" # hello world
echo "${s^^}" # HELLO WORLD
歷史意義#
Bash 4.0 讓 bash 的資料結構(索引陣列 + 關聯陣列)與檔名展開(globstar)追上 zsh/ksh93,確立了「bash 腳本」超越「POSIX 腳本」的表達力優勢。之後 2016 年 bash 4.4(-v 變數追蹤)、2019 年 bash 5.0(EPOCHSECONDS)持續小步擴充。
彌補了什麼缺陷#
彌補了 bash「無關聯陣列、glob 不遞迴、管線單向」的表達力缺陷,大幅減少對外部程式(find、awk、tr)的依賴。