if 語句的核心是 test / [ ] / [[ ]] 的判斷表達式。本文將所有常用測試運算符按類別整理成表,方便寫腳本時秒級查閱。
一、文件屬性測試
| 運算符 | 真條件 |
-a FILE / -e FILE | 文件存在 |
-b FILE | 存在且為塊設備 |
-c FILE | 存在且為字符設備 |
-d FILE | 存在且為目錄 |
-f FILE | 存在且為普通文件 |
-g FILE | 存在且設置了 SGID |
-h FILE / -L FILE | 存在且為符號鏈接 |
-k FILE | 存在且設置了粘著位 |
-p FILE | 存在且為命名管道 (FIFO) |
-r FILE | 存在且可讀 |
-s FILE | 存在且大小非 0 |
-t FD | 文件描述符 FD 打開且指向終端 |
-u FILE | 存在且設置了 SUID |
-w FILE | 存在且可寫 |
-x FILE | 存在且可執行 |
-O FILE | 存在且屬於有效用戶 ID |
-G FILE | 存在且屬於有效用戶組 |
-N FILE | 存在且自上次讀取後被修改過 |
-S FILE | 存在且為 Socket |
二、文件時間/關係比較
| 運算符 | 真條件 |
FILE1 -nt FILE2 | FILE1 比 FILE2 新,或 FILE1 存在且 FILE2 不存在 |
FILE1 -ot FILE2 | FILE1 比 FILE2 舊,或 FILE2 存在且 FILE1 不存在 |
FILE1 -ef FILE2 | FILE1 和 FILE2 指向同一設備同一 inode(硬鏈接/同一文件) |
三、字符串測試
| 運算符 | 真條件 |
-z STRING | 字符串長度為 0 |
-n STRING / [ STRING ] | 字符串長度非 0 |
STRING1 == STRING2 / STRING1 = STRING2 | 字符串相等([[ ]] 中 == 支持 glob) |
STRING1 != STRING2 | 字符串不相等([[ ]] 中支持 glob) |
STRING1 < STRING2 | 字典序排在前(需 [[ ]] 或 [ ] 轉義) |
STRING1 > STRING2 | 字典序排在後 |
四、數值比較(僅限整數)
| 運算符 | 含義 |
ARG1 -eq ARG2 | 等於 |
ARG1 -ne ARG2 | 不等於 |
ARG1 -lt ARG2 | 小於 |
ARG1 -le ARG2 | 小於等於 |
ARG1 -gt ARG2 | 大於 |
ARG1 -ge ARG2 | 大於等於 |
提示:在 (( )) 中可直接用 < > <= >= == !=,變量無需 $。
五、Shell 選項測試
| 運算符 | 真條件 |
-o OPTIONNAME | Shell 選項 OPTIONNAME 開啟(如 set -o noclobber) |
六、組合邏輯
| 運算符 | 用法 | 環境 |
! EXPR | 邏輯非 | [ ] [[ ]] |
EXPR1 -a EXPR2 | 邏輯與 | [ ](不推薦) |
EXPR1 -o EXPR2 | 邏輯或 | [ ](不推薦) |
EXPR1 && EXPR2 | 邏輯與(短路) | [[ ]] (( )) |
EXPR1 || EXPR2 | 邏輯或(短路) | [[ ]] (( )) |
七、實戰模板
#!/bin/bash
set -euo pipefail
file="/etc/passwd"
user="root"
# 文件存在且可讀
if [[ -f "$file" && -r "$file" ]]; then
echo "文件可讀"
fi
# 字符串非空且以 root 開頭
if [[ -n "$user" && "$user" == root* ]]; then
echo "管理員相關用戶"
fi
# 數值比較
count=5
if (( count > 3 )); then
echo "計數超標"
fi
# 組合:文件較新且大小非零
if [[ "$file" -nt /tmp/stamp && -s "$file" ]]; then
echo "有更新且非空"
fi
八、避坑清單
- 變量必須加雙引號:
[[ -n "$var" ]],防止空串導致語法錯誤。
- 優先用
[[ ]] 和 (( )):原生支持 && || < > =~,不進行 word splitting/glob 展開。
- 文件比較
-nt/-ot/-ef 會自動處理不存在情況:按表中定義返回真/假,無需額外 -e 判斷。
- 數值比較僅支持整數:浮點數請用
bc、awk 或 zsh 內建。
總結
收藏本表,寫 if 時不再翻手冊。記住核心口訣:文件看屬性時間,字符串看長度匹配,數值進雙圓括號,邏輯用雙符號,變量必須加引號。