Bash 讀取每行輸入 (管道行) 經歷 12 個處理階段,理解這流程能避免 90% 的腳本 Bug。本文結合流程圖詳細解析每階段行為與實戰技巧。
;、(、)、<、>、|、&)if/while/function/{/(){a,b}c → ac bc~user → 家目錄$var、${var:-default}、${#var} 等 (雙引號內執行)$(cmd) / `cmd` (遞歸處理命令行)$((expr)) (雙引號內執行)IFS 分割 (雙引號內抑制)* ? [...] (雙引號內抑制)| 機制 | 單引號 '' | 雙引號 "" | 無引號 |
|---|---|---|---|
| 參數展開 | 否 | 是 | 是 |
| 命令替換 | 否 | 是 | 是 |
| 算術展開 | 否 | 是 | 是 |
| 單詞分割 | 否 | 否 | 是 |
| 路徑展開 | 否 | 否 | 是 |
| 字面意義 | 完全保留 | 部分保留 | 無 |
eval:再次掃描命令行 (步驟 1-12),慎用,注入風險高arr=(a b c)、"${arr[@]}" 保持元素邊界IFS 修改影響單詞分割,建議局部修改:IFS=, read -ra arr <<< "$str"set -x 追蹤展開後命令、bash -x script.sh
# 陷阱 1:for 迴圈未加引號
for f in *.txt; do echo $f; done # 正常
for f in $files; do echo $f; done # $files 含空格會錯誤分割
# 陷阱 2:命令替換未加引號
echo $(ls) # 結果經單詞分割+路徑展開
echo "$(ls)" # 保留換行與空格
# 陷阱 3:別名遞歸
alias ls='ls --color=auto'
ls # 展開為 ls --color=auto,首 Token 仍為 ls,但步驟3不再展開 (避免無限遞歸)
Bash 命令行 12 步驟是 Shell 腳本行為的底層邏輯。掌握 引號抑制展開、參數/命令/算術展開順序、IFS 分割、路徑展開時機,能寫出健壯、可預測、安全的腳本。建議配合 shellcheck 靜態分析工具檢查常見問題。