循环不一定非要执行完。有时候需要提前退出,或者跳过当前迭代。break 和 continue 就是干这个的。
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 用于跳过当前迭代,继续下一次:
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:完全退出循环
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 中使用 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
循环控制要点: