Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux Shell 流程控制完全指南:if/for/while/until/case/select 實戰範例與最佳實踐

編輯:Linux 教學

Shell 腳本的流程控制結構 (條件判斷、迴圈、分支選擇) 是自動化運維、資料處理、部署管線的核心骨架。本文系統整理 if/elif/else/fi、for/while/until、case/esac、select 完整語法、實戰範例、常見陷阱與現代最佳實踐 (Bash 4/5 新特性)。

一、條件判斷:if/elif/else/fi

1. 基本結構


if [[ condition ]]; then
    action
elif [[ condition ]]; then
    action
else
    action
fi

關鍵規則:[[ ... ]] 為 Bash 擴展測試命令,**優於單括號 [ ... ]** (支援 &&/||/</>/=~ 正則、變數無需雙引號)。

2. 常用測試運算子速查

類別運算子說明範例
檔案測試-e存在[[ -e file ]]
-f一般檔案[[ -f file ]]
-d目錄[[ -d dir ]]
-r/-w/-x可讀/寫/執行[[ -x script.sh ]]
-s大小 > 0[[ -s log.txt ]]
-L符號連結[[ -L link ]]
字串測試-z長度為 0[[ -z "$var" ]]
-n長度非 0[[ -n "$var" ]]
==/!=相等/不等 (支援 glob 模式)[[ "$str" == *.txt ]]
=~正則比對 (Bash 3.2+)[[ "$email" =~ ^[^@]+@[^@]+\.[^@]+$ ]]
</>字典序比較[[ "a" < "b" ]]
整數比較-eq/-ne等於/不等於[[ $a -eq 10 ]]
-lt/-le小於/小於等於[[ $a -lt 100 ]]
-gt/-ge大於/大於等於[[ $a -gt 0 ]]
(())算術語境 (支援 < > <= >= == !=)(( a > 10 ))
邏輯組合&&/||/!且/或/非 (僅 [[ ]] 與 (( )))[[ -f $f && -r $f ]]

3. 實戰範例:分數等級判斷


#!/bin/bash
score=78
if (( score >= 90 )); then
    echo "優等"
elif (( score >= 80 )); then
    echo "甲等"
elif (( score >= 70 )); then
    echo "乙等"
elif (( score >= 60 )); then
    echo "及格"
else
    echo "不及格"
fi

二、迴圈結構

1. for 迴圈三種形式


# 形式 A: for 變數 in 列表 (最常用)
for i in {1..5}; do
    echo $i
done

# 形式 B: C 風格算術 for (( ; ; ))
for ((i=1; i<=5; i++)); do
    echo $i
done

# 形式 C: 遍歷陣列/命令輸出
files=(/var/log/*.log)
for f in "${files[@]}"; do
    echo "Processing $f"
done

2. while 迴圈:條件前測試


# 計數器
i=10
while (( i > 5 )); do
    echo $i
    ((i--))
done

# 逐行讀取檔案 (標準模式,保留前導/尾隨空白)
while IFS= read -r line; do
    echo "Line: $line"
done < /etc/hosts

# 讀取命令輸出 (避免 subshell 變數作用域問題)
find /tmp -name "*.tmp" -print0 |
while IFS= read -r -d '' file; do
    rm -f "$file"
done

3. until 迴圈:條件後測試 (直到為真才結束)


a=10
until (( a < 0 )); do
    echo $a
    ((a--))
done
# 輸出 10 9 8 7 6 5 4 3 2 1 0

4. 迴圈控制:break / continue


for i in {1..10}; do
    (( i == 5 )) && continue   # 跳過 5
    (( i == 8 )) && break      # 8 時結束
    echo $i
done
# 輸出 1 2 3 4 6 7

三、分支選擇:case/esac

1. 語法與模式匹配


case $1 in
    start|begin)
        echo "啟動服務"
        ;;
    stop|end)
        echo "停止服務"
        ;;
    restart|reload)
        echo "重啟服務"
        ;;
    status)
        systemctl status myservice
        ;;
    *)
        echo "用法: $0 {start|stop|restart|status}"
        exit 1
        ;;
esac

模式支援:* (任意字串)、? (單字元)、[abc] (字元類)、[a-z] (範圍)、| (多選)。

2. 進階:Fallthrough (;;& / ;&)


# Bash 4+ 支援
case $var in
    pattern1) action1 ;;&   # 繼續測試下一模式
    pattern2) action2 ;&    # 執行下一動作不再測試
    *) default_action ;;
esac

四、選單互動:select


PS3="請選擇操作: "
options=("啟動" "停止" "重啟" "狀態" "離開")
select opt in "${options[@]}"; do
    case $opt in
        "啟動")   systemctl start myservice ;;
        "停止")   systemctl stop myservice ;;
        "重啟")   systemctl restart myservice ;;
        "狀態")   systemctl status myservice ;;
        "離開")   echo "再見"; break ;;
        *)        echo "無效選項 $REPLY" ;;
    esac
done

select 內建無限迴圈,需配合 break 退出。

五、現代最佳實踐 (Bash 4/5)

  1. 永遠使用 [[ ]] 和 (( )),避免 [ ] 詞語分割與檔名展開 Bug。
  2. 變數加雙引號:"$var",除非刻意要詞語分割。
  3. 迴圈讀取檔案用 while IFS= read -r line,保留空白與反斜線。
  4. 避免在管道中修改外部變數 (Subshell 隔離),改用 while ... done < <(cmd) (Process Substitution) 或 mapfile。
  5. 使用 case 替代長鏈 if/elif,可讀性與效能更佳。
  6. 啟用 set -euo pipefail (腳本開頭),嚴格錯誤處理。
  7. 函數化邏輯,主流程只呼叫函數,便於測試與複用。

六、除錯技巧


# 1. 語法檢查
bash -n script.sh

# 2. 逐行追蹤執行
bash -x script.sh
# 或腳本內動態開關
set -x  # 開啟追蹤
set +x  # 關閉追蹤

# 3. 列印變數值
echo "DEBUG: var=$var" >&2

# 4. ShellCheck 靜態分析 (強烈推薦)
shellcheck script.sh

掌握 Shell 流程控制的完整語法、模式匹配威力、現代最佳實踐與除錯工具,能讓自動化腳本從「能跑」進化為「健壯、可維護、可測試」的生產級代碼資產。

Copyright © Windows教程網 All Rights Reserved