循环控制 #
一、break语句 #
1.1 基本用法 #
break语句用于跳出当前循环:
bash
#!/bin/bash
# 基本break使用
for i in {1..10}; do
if [ $i -eq 5 ]; then
echo "遇到5,跳出循环"
break
fi
echo "数字: $i"
done
echo "循环结束"
1.2 跳出多层循环 #
bash
#!/bin/bash
# 跳出单层循环
for i in {1..3}; do
for j in {1..3}; do
if [ $j -eq 2 ]; then
break # 只跳出内层循环
fi
echo "i=$i, j=$j"
done
done
echo "---"
# 跳出多层循环
for i in {1..3}; do
for j in {1..3}; do
if [ $i -eq 2 ] && [ $j -eq 2 ]; then
break 2 # 跳出两层循环
fi
echo "i=$i, j=$j"
done
done
echo "循环结束"
1.3 break在while中的应用 #
bash
#!/bin/bash
# 条件退出
count=0
while true; do
((count++))
echo "计数: $count"
if [ $count -ge 5 ]; then
echo "达到上限,退出"
break
fi
sleep 1
done
# 用户输入退出
while true; do
read -p "输入命令 (q退出): " cmd
case "$cmd" in
q|Q|quit|exit)
echo "再见!"
break
;;
*)
echo "执行: $cmd"
;;
esac
done
二、continue语句 #
2.1 基本用法 #
continue语句用于跳过本次迭代,继续下一次循环:
bash
#!/bin/bash
# 基本continue使用
for i in {1..10}; do
if [ $((i % 2)) -eq 0 ]; then
continue # 跳过偶数
fi
echo "奇数: $i"
done
# 跳过特定条件
for file in *.txt; do
if [ ! -r "$file" ]; then
echo "跳过不可读文件: $file"
continue
fi
echo "处理文件: $file"
# 处理逻辑
done
2.2 continue在while中的应用 #
bash
#!/bin/bash
# 跳过特定行
while IFS= read -r line; do
# 跳过空行
if [ -z "$line" ]; then
continue
fi
# 跳过注释行
if [[ "$line" =~ ^# ]]; then
continue
fi
echo "处理: $line"
done < file.txt
# 跳过无效输入
while true; do
read -p "输入数字 (0退出): " num
# 退出条件
if [ "$num" = "0" ]; then
break
fi
# 验证输入
if ! [[ "$num" =~ ^[0-9]+$ ]]; then
echo "无效输入,请输入数字"
continue
fi
echo "输入的数字: $num"
done
2.3 跳过多层循环 #
bash
#!/bin/bash
# continue跳过外层循环
for i in {1..3}; do
for j in {1..3}; do
if [ $j -eq 2 ]; then
continue 2 # 跳到外层循环的下一次迭代
fi
echo "i=$i, j=$j"
done
done
三、循环控制实战 #
3.1 查找第一个匹配项 #
bash
#!/bin/bash
# 查找第一个包含关键字的文件
find_first_match() {
local keyword="$1"
local dir="${2:-.}"
for file in "$dir"/*; do
if [ -f "$file" ] && grep -q "$keyword" "$file"; then
echo "找到匹配文件: $file"
break
fi
done
}
find_first_match "error" "/var/log"
# 查找第一个可用的服务
find_available_service() {
local services=("nginx" "apache2" "httpd")
for service in "${services[@]}"; do
if systemctl is-active --quiet "$service" 2>/dev/null; then
echo "可用服务: $service"
break
fi
done
}
3.2 数据验证 #
bash
#!/bin/bash
# 验证所有文件是否可读
validate_files() {
local all_ok=true
for file in "$@"; do
if [ ! -f "$file" ]; then
echo "错误: 文件不存在: $file"
all_ok=false
continue
fi
if [ ! -r "$file" ]; then
echo "错误: 文件不可读: $file"
all_ok=false
continue
fi
echo "验证通过: $file"
done
$all_ok
}
# 验证配置
validate_config() {
local config_file="$1"
while IFS='=' read -r key value; do
# 跳过注释和空行
[[ "$key" =~ ^#.*$ ]] && continue
[[ -z "$key" ]] && continue
# 验证必需配置
if [ -z "$value" ]; then
echo "错误: $key 未设置值"
break
fi
echo "$key = $value"
done < "$config_file"
}
3.3 批量处理 #
bash
#!/bin/bash
# 批量处理文件,跳过错误
process_files() {
local success=0
local failed=0
for file in "$@"; do
# 检查文件
if [ ! -f "$file" ]; then
echo "跳过: $file (不存在)"
((failed++))
continue
fi
# 处理文件
if process_one "$file"; then
echo "成功: $file"
((success++))
else
echo "失败: $file"
((failed++))
fi
done
echo "处理完成: 成功 $success, 失败 $failed"
}
# 带重试的处理
process_with_retry() {
local file="$1"
local max_retries=3
local retry=0
while [ $retry -lt $max_retries ]; do
if process_one "$file"; then
return 0
fi
((retry++))
echo "重试 $retry/$max_retries: $file"
sleep 1
done
return 1
}
3.4 交互式菜单 #
bash
#!/bin/bash
show_menu() {
echo "========================"
echo " 主菜单"
echo "========================"
echo "1. 选项一"
echo "2. 选项二"
echo "3. 选项三"
echo "4. 返回上级"
echo "5. 退出"
echo "========================"
}
submenu() {
while true; do
echo "=== 子菜单 ==="
echo "1. 子选项一"
echo "2. 子选项二"
echo "3. 返回"
read -p "选择: " sub_choice
case $sub_choice in
1) echo "执行子选项一" ;;
2) echo "执行子选项二" ;;
3) break ;; # 返回主菜单
*) echo "无效选择" ;;
esac
done
}
# 主循环
while true; do
show_menu
read -p "请选择: " choice
case $choice in
1)
echo "执行选项一"
;;
2)
echo "执行选项二"
;;
3)
submenu # 进入子菜单
;;
4)
echo "返回上级"
continue # 继续主循环
;;
5)
echo "退出系统"
break # 退出主循环
;;
*)
echo "无效选择,请重新输入"
continue
;;
esac
read -p "按回车继续..."
done
四、循环控制最佳实践 #
4.1 使用函数简化循环 #
bash
#!/bin/bash
# 不推荐:复杂的循环逻辑
for file in *.txt; do
if [ -f "$file" ]; then
if [ -r "$file" ]; then
if [ -s "$file" ]; then
# 处理逻辑
echo "处理: $file"
fi
fi
fi
done
# 推荐:使用函数封装
is_valid_file() {
local file="$1"
[ -f "$file" ] && [ -r "$file" ] && [ -s "$file" ]
}
for file in *.txt; do
is_valid_file "$file" || continue
echo "处理: $file"
done
4.2 避免深层嵌套 #
bash
#!/bin/bash
# 不推荐:深层嵌套
for item in "$@"; do
if [ -n "$item" ]; then
if [ -f "$item" ]; then
if [ -r "$item" ]; then
echo "处理: $item"
else
echo "不可读: $item"
fi
else
echo "不是文件: $item"
fi
else
echo "空参数"
fi
done
# 推荐:提前退出
for item in "$@"; do
[ -z "$item" ] && { echo "空参数"; continue; }
[ ! -f "$item" ] && { echo "不是文件: $item"; continue; }
[ ! -r "$item" ] && { echo "不可读: $item"; continue; }
echo "处理: $item"
done
4.3 使用标签(Bash 4.0+) #
bash
#!/bin/bash
# 使用标签跳出多层循环
outer:
for i in {1..3}; do
for j in {1..3}; do
for k in {1..3}; do
if [ $i -eq 2 ] && [ $j -eq 2 ]; then
break outer
fi
echo "i=$i, j=$j, k=$k"
done
done
done
echo "跳出所有循环"
五、循环控制速查 #
5.1 控制语句 #
| 语句 | 说明 | 示例 |
|---|---|---|
| break | 跳出循环 | break |
| break n | 跳出n层循环 | break 2 |
| continue | 跳过本次迭代 | continue |
| continue n | 跳过n层循环的本次迭代 | continue 2 |
| exit | 退出脚本 | exit 0 |
| return | 退出函数 | return 0 |
5.2 使用场景 #
| 场景 | 推荐语句 |
|---|---|
| 找到目标后退出 | break |
| 跳过无效数据 | continue |
| 遇到错误退出 | exit |
| 函数返回 | return |
六、总结 #
6.1 循环控制要点 #
| 要点 | 说明 |
|---|---|
| break | 完全跳出循环 |
| continue | 跳过本次迭代 |
| break n | 跳出n层循环 |
| continue n | 跳过n层循环的本次迭代 |
| 使用场景 | 条件退出、跳过无效数据 |
6.2 下一步 #
你已经掌握了循环控制,接下来让我们学习 函数基础,了解Shell函数的定义和使用!
最后更新:2026-03-27