while循环 #
一、while循环基础 #
1.1 基本语法 #
bash
while [ 条件 ]; do
命令
done
1.2 简单示例 #
bash
#!/bin/bash
# 基本计数
count=1
while [ $count -le 5 ]; do
echo "计数: $count"
((count++))
done
# 使用 (( ))
num=0
while (( num < 5 )); do
echo "数字: $num"
((num++))
done
二、while循环应用 #
2.1 读取文件 #
bash
#!/bin/bash
# 逐行读取文件
while IFS= read -r line; do
echo "行: $line"
done < file.txt
# 读取带分隔符的文件
while IFS=',' read -r name age city; do
echo "姓名: $name, 年龄: $age, 城市: $city"
done < data.csv
# 从命令输出读取
while read -r line; do
echo "处理: $line"
done < <(ls -la)
2.2 用户输入处理 #
bash
#!/bin/bash
# 持续获取输入直到退出
while true; do
read -p "请输入命令 (q退出): " cmd
case "$cmd" in
q|Q|quit|exit)
echo "再见!"
break
;;
*)
echo "执行: $cmd"
;;
esac
done
# 验证输入
while true; do
read -p "请输入数字: " num
if [[ "$num" =~ ^[0-9]+$ ]]; then
echo "输入正确: $num"
break
else
echo "请输入有效数字"
fi
done
2.3 等待条件满足 #
bash
#!/bin/bash
# 等待服务启动
echo "等待服务启动..."
while ! systemctl is-active --quiet nginx; do
echo "等待中..."
sleep 1
done
echo "服务已启动"
# 等待文件创建
file="/tmp/signal"
while [ ! -f "$file" ]; do
echo "等待文件 $file ..."
sleep 1
done
echo "文件已创建"
# 等待进程结束
pid=12345
while kill -0 $pid 2>/dev/null; do
echo "进程 $pid 仍在运行..."
sleep 1
done
echo "进程已结束"
2.4 倒计时 #
bash
#!/bin/bash
# 简单倒计时
count=10
while [ $count -gt 0 ]; do
echo "倒计时: $count"
sleep 1
((count--))
done
echo "时间到!"
# 格式化倒计时
seconds=90
while [ $seconds -gt 0 ]; do
mins=$((seconds / 60))
secs=$((seconds % 60))
printf "\r剩余时间: %02d:%02d" $mins $secs
sleep 1
((seconds--))
done
echo ""
echo "完成!"
三、无限循环 #
3.1 创建无限循环 #
bash
#!/bin/bash
# 方式一:while true
while true; do
echo "运行中..."
sleep 1
done
# 方式二:while :
while :; do
echo "运行中..."
sleep 1
done
# 方式三:while [ 1 ]
while [ 1 ]; do
echo "运行中..."
sleep 1
done
3.2 守护进程示例 #
bash
#!/bin/bash
# 简单守护进程
daemon() {
local pidfile="/tmp/mydaemon.pid"
# 检查是否已运行
if [ -f "$pidfile" ]; then
pid=$(cat "$pidfile")
if kill -0 "$pid" 2>/dev/null; then
echo "守护进程已在运行 (PID: $pid)"
return 1
fi
fi
# 写入PID
echo $$ > "$pidfile"
# 主循环
while true; do
# 执行任务
echo "$(date): 执行任务..."
# 检查是否需要退出
if [ -f "/tmp/stop_daemon" ]; then
rm -f "/tmp/stop_daemon"
break
fi
sleep 60
done
# 清理
rm -f "$pidfile"
echo "守护进程退出"
}
daemon
3.3 监控脚本 #
bash
#!/bin/bash
# 系统监控
monitor() {
local interval=5
while true; do
clear
echo "=== 系统监控 ==="
echo "时间: $(date)"
echo ""
# CPU使用率
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}')
echo "CPU使用率: ${cpu_usage}%"
# 内存使用
mem_info=$(free -m | awk 'NR==2{printf "%.1f%%", $3*100/$2}')
echo "内存使用: $mem_info"
# 磁盘使用
disk_info=$(df -h / | awk 'NR==2{print $5}')
echo "磁盘使用: $disk_info"
# 网络连接数
conn_count=$(netstat -an | grep ESTABLISHED | wc -l)
echo "网络连接: $conn_count"
sleep "$interval"
done
}
monitor
四、while循环高级用法 #
4.1 多条件循环 #
bash
#!/bin/bash
# 使用 (( )) 进行多条件判断
a=0
b=10
while (( a < 5 && b > 5 )); do
echo "a=$a, b=$b"
((a++))
((b--))
done
# 使用 [[ ]] 进行多条件判断
file_count=0
max_files=10
while [[ $file_count -lt $max_files && -f "file_${file_count}.txt" ]]; do
echo "处理文件: file_${file_count}.txt"
((file_count++))
done
4.2 嵌套while循环 #
bash
#!/bin/bash
# 打印乘法表
i=1
while [ $i -le 9 ]; do
j=1
while [ $j -le $i ]; do
printf "%d*%d=%-4d" $j $i $((j*i))
((j++))
done
echo ""
((i++))
done
# 读取多个文件
while IFS= read -r file1; do
while IFS= read -r file2; do
echo "比较: $file1 vs $file2"
done < file2.txt
done < file1.txt
4.3 读取管道输入 #
bash
#!/bin/bash
# 从管道读取
echo -e "line1\nline2\nline3" | while read -r line; do
echo "处理: $line"
done
# 注意:管道中的while在子Shell中执行
count=0
echo -e "1\n2\n3" | while read -r num; do
((count++))
done
echo "计数: $count" # 输出: 0(子Shell中的修改不生效)
# 解决方案:使用进程替换
count=0
while read -r num; do
((count++))
done < <(echo -e "1\n2\n3")
echo "计数: $count" # 输出: 3
五、实战示例 #
5.1 菜单系统 #
bash
#!/bin/bash
show_menu() {
clear
echo "========================"
echo " 系统管理菜单"
echo "========================"
echo "1. 查看系统信息"
echo "2. 查看磁盘使用"
echo "3. 查看内存使用"
echo "4. 查看进程列表"
echo "5. 退出"
echo "========================"
}
while true; do
show_menu
read -p "请选择 [1-5]: " choice
case $choice in
1)
echo "=== 系统信息 ==="
uname -a
;;
2)
echo "=== 磁盘使用 ==="
df -h
;;
3)
echo "=== 内存使用 ==="
free -h
;;
4)
echo "=== 进程列表 ==="
ps aux | head -20
;;
5)
echo "再见!"
exit 0
;;
*)
echo "无效选择"
;;
esac
read -p "按回车继续..."
done
5.2 日志监控 #
bash
#!/bin/bash
log_file="/var/log/syslog"
pattern="ERROR"
echo "监控日志文件: $log_file"
echo "监控模式: $pattern"
echo ""
# 使用tail -f持续监控
tail -f "$log_file" | while read -r line; do
if echo "$line" | grep -q "$pattern"; then
echo "[ALERT] $line"
# 可以添加告警逻辑
fi
done
5.3 重试机制 #
bash
#!/bin/bash
# 带重试的命令执行
retry_command() {
local max_attempts=$1
local command="$2"
local attempt=1
while [ $attempt -le $max_attempts ]; do
echo "尝试 $attempt/$max_attempts: $command"
if eval "$command"; then
echo "成功!"
return 0
fi
echo "失败,等待重试..."
sleep 2
((attempt++))
done
echo "达到最大重试次数"
return 1
}
retry_command 3 "curl -f http://example.com/api"
5.4 进度监控 #
bash
#!/bin/bash
# 监控后台任务进度
monitor_progress() {
local pid=$1
local total=$2
local current=0
while kill -0 "$pid" 2>/dev/null; do
# 模拟进度更新
current=$((current + 1))
if [ $current -gt $total ]; then
current=$total
fi
percent=$((current * 100 / total))
printf "\r进度: %d/%d (%d%%)" $current $total $percent
sleep 0.5
done
echo ""
echo "任务完成"
}
# 启动后台任务
sleep 10 &
pid=$!
monitor_progress $pid 20
六、while循环最佳实践 #
6.1 避免常见错误 #
bash
#!/bin/bash
# 错误:变量未加引号
file=""
while [ $file != "exit" ]; do # 如果file为空会报错
read -p "输入: " file
done
# 正确:变量加引号
file=""
while [ "$file" != "exit" ]; do
read -p "输入: " file
done
# 错误:死循环
while true; do
echo "运行中"
# 忘记退出条件
done
# 正确:有退出条件
while true; do
echo "运行中"
read -p "继续? (y/n): " choice
[ "$choice" = "n" ] && break
done
6.2 性能考虑 #
bash
#!/bin/bash
# 不推荐:频繁执行外部命令
while true; do
date # 每次都执行外部命令
sleep 1
done
# 推荐:使用内置命令
while true; do
printf '%(%Y-%m-%d %H:%M:%S)T\n' -1 # Bash内置
sleep 1
done
# 推荐:减少循环次数
count=0
while [ $count -lt 1000 ]; do
# 批量处理而不是逐个处理
((count++))
done
七、while循环速查 #
7.1 常用模式 #
| 模式 | 示例 |
|---|---|
| 条件循环 | while [ $i -lt 10 ]; do … done |
| 无限循环 | while true; do … done |
| 读取文件 | while read line; do … done < file |
| 读取输入 | while read -p "输入: " var; do … done |
| 等待条件 | while [ ! -f file ]; do sleep 1; done |
7.2 控制命令 #
| 命令 | 说明 |
|---|---|
| break | 跳出循环 |
| continue | 跳过本次迭代 |
| exit | 退出脚本 |
| return | 退出函数 |
八、总结 #
8.1 while循环要点 #
| 要点 | 说明 |
|---|---|
| 基本语法 | while [ 条件 ]; do … done |
| 无限循环 | while true 或 while : |
| 读取文件 | while read line; do … done < file |
| 条件等待 | 配合 sleep 使用 |
| 退出控制 | 使用 break 和 continue |
8.2 下一步 #
你已经掌握了while循环,接下来让我们学习 until循环,了解直到型循环!
最后更新:2026-03-27