跳轉到

建立 2026-09-14 更新 2026-09-14

條件判斷

腳本跟互動指令的差別,多半就在「如果失敗就停、如果檔存在才複製」。Bash 用結束碼判斷真假:0 為真(成功),非 0 為假。

if 的形狀

if grep -q error app.log; then
  echo "發現錯誤"
elif grep -q warn app.log; then
  echo "只有警告"
else
  echo "看起來正常"
fi

then / fi 是固定關鍵字。條件位置其實就是一道指令;grep -q 找到就回傳 0。

一行寫:

[ -d /tmp/cache ] && rm -r /tmp/cache
[ -f config.env ] || echo "缺少 config.env"

&&:左邊成功才做右邊。||:左邊失敗才做右邊。

test[[ ]]

檔案與字串比對用 test,常見寫成 [ ](兩邊要空格):

if [ -f "$file" ]; then
  echo "是一般檔"
fi

if [ ! -d "$dir" ]; then
  mkdir -p "$dir"
fi
條件 意義
-f 一般檔存在
-d 目錄存在
-e 存在(任何類型)
-x 可執行
-z "$s" 字串長度為 0
-n "$s" 字串非空
"$a" = "$b" 字串相等(不要寫成 == 在單括號裡硬記兩套)
"$n" -gt 10 整數大於(另有 -eq -lt -ge -le -ne

Bash 還有 [[ ]],比較不容易被空白與萬用字元咬到,也支援 &&||=~ 正規表示式:

if [[ $name == alice && -d $HOME ]]; then
  echo "ok"
fi

if [[ $email =~ ^[^@]+@[^@]+$ ]]; then
  echo "像是 email"
fi

新腳本建議用 [[ ]];看舊教材時要認得 [ ] 是同一類東西。

case

多個固定字串用 case 比一串 elif 清楚:

case "$1" in
  start)  echo "啟動" ;;
  stop)   echo "停止" ;;
  restart) echo "重啟" ;;
  *)      echo "用法:$0 {start|stop|restart}" >&2
          exit 1 ;;
esac

;; 結束一個分支,*) 是預設。錯誤訊息丟到 >&2(stderr),結束碼用非 0。

結束碼

cp "$src" "$dest"
if [ $? -ne 0 ]; then
  echo "複製失敗" >&2
  exit 1
fi

set -e 時,失敗的 cp 會直接讓腳本結束,不一定要手動查 $?。需要「失敗也繼續」時再檢查 $? 或用 if cp ...; then

exit 0    # 成功(預設)
exit 1    # 一般錯誤

crontab 與 CI 都靠結束碼決定要不要告警。

總結

條件就是指令成不成功。檔案與字串用 [[ ]],多個固定選項用 case,對外失敗用 exit 1。重複做同一件事則看 迴圈