循环控制

循环不一定非要执行完。有时候需要提前退出,或者跳过当前迭代。break 和 continue 就是干这个的。

break 语句

break 用于跳出整个循环:

for I in {1..10}; do
    if [ $I -eq 5 ]; then
        echo "遇到 5,退出循环"
        break
    fi
    echo "数字: $I"
done

# 输出:
# 数字: 1
# 数字: 2
# 数字: 3
# 数字: 4
# 遇到 5,退出循环

continue 语句

continue 用于跳过当前迭代,继续下一次:

for I in {1..5}; do
    if [ $I -eq 3 ]; then
        echo "跳过 3"
        continue
    fi
    echo "数字: $I"
done

# 输出:
# 数字: 1
# 数字: 2
# 跳过 3
# 数字: 4
# 数字: 5

跳出多层循环

默认情况下,break 只跳出当前层循环。要跳出多层,可以用数字指定:

for I in {1..3}; do
    for J in {1..3}; do
        if [ $I -eq 2 ] && [ $J -eq 2 ]; then
            echo "跳出两层循环"
            break 2
        fi
        echo "I=$I, J=$J"
    done
done

break 2 跳出两层循环,break 1 等同于 break

实际应用

查找文件并退出

#!/bin/bash

for DIR in /usr /var /home; do
    if [ -f "$DIR/target.txt" ]; then
        echo "找到文件: $DIR/target.txt"
        break
    fi
done

跳过无效输入

#!/bin/bash

for ITEM in "apple" "" "banana" "   " "orange"; do
    # 跳过空值或纯空格
    if [ -z "$(echo $ITEM | tr -d ' ')" ]; then
        continue
    fi
    echo "处理: $ITEM"
done

处理文件跳过错误

#!/bin/bash

for FILE in *.txt; do
    if [ ! -r "$FILE" ]; then
        echo "跳过不可读文件: $FILE"
        continue
    fi
    
    # 处理文件
    echo "处理: $FILE"
done

带确认的循环

#!/bin/bash

while true; do
    read -p "继续吗?(y/n): " ANSWER
    
    case $ANSWER in
        y|Y)
            echo "继续执行..."
            ;;
        n|N)
            echo "退出"
            break
            ;;
        *)
            echo "无效输入,请重新输入"
            continue
            ;;
    esac
    
    # 执行操作
    echo "执行操作..."
done

条件满足时退出

#!/bin/bash

COUNT=0
MAX_ERRORS=3

while read LINE; do
    if echo "$LINE" | grep -q "ERROR"; then
        COUNT=$((COUNT + 1))
        echo "发现错误 ($COUNT/$MAX_ERRORS)"
        
        if [ $COUNT -ge $MAX_ERRORS ]; then
            echo "错误次数过多,退出"
            break
        fi
    fi
done < app.log

break 与 continue 的区别

# break:完全退出循环
for I in {1..5}; do
    if [ $I -eq 3 ]; then
        break
    fi
    echo $I
done
# 输出:1 2

# continue:跳过当前,继续下一次
for I in {1..5}; do
    if [ $I -eq 3 ]; then
        continue
    fi
    echo $I
done
# 输出:1 2 4 5

在 while 和 until 中使用

# while 中使用 break
COUNT=0
while true; do
    COUNT=$((COUNT + 1))
    if [ $COUNT -gt 5 ]; then
        break
    fi
    echo $COUNT
done

# until 中使用 continue
COUNT=0
until [ $COUNT -gt 5 ]; do
    COUNT=$((COUNT + 1))
    if [ $COUNT -eq 3 ]; then
        continue
    fi
    echo $COUNT
done

使用标志变量

有时候用标志变量比 break 更清晰:

#!/bin/bash

FOUND=false

for FILE in *.txt; do
    if grep -q "keyword" "$FILE"; then
        FOUND=true
        echo "在 $FILE 中找到关键字"
    fi
done

if [ "$FOUND" = true ]; then
    echo "搜索完成,找到匹配"
else
    echo "搜索完成,未找到匹配"
fi

小结

循环控制要点:

  1. break 跳出整个循环
  2. continue 跳过当前迭代
  3. break N 跳出 N 层循环
  4. 合理使用让代码更清晰
  5. 复杂逻辑可用标志变量替代