while 循环在条件为真时重复执行,适合条件驱动的场景。和 for 循环不同,while 不需要提前知道循环次数。
while [ 条件 ]; do
命令
done
条件为真时执行循环体,条件为假时退出。
COUNT=1
while [ $COUNT -le 5 ]; do
echo "计数: $COUNT"
COUNT=$((COUNT + 1))
done
while 最常见的用途是逐行读取文件:
# 方式一
while read LINE; do
echo "行: $LINE"
done < file.txt
# 方式二(保留空格)
while IFS= read -r LINE; do
echo "行: $LINE"
done < file.txt
# 方式三(读取多列)
while read COL1 COL2 REST; do
echo "第一列: $COL1"
echo "第二列: $COL2"
done < data.txt
IFS= 防止行首行尾空格被去掉,-r 防止反斜杠被转义。
while true; do
read -p "请输入 (q 退出): " INPUT
if [ "$INPUT" = "q" ]; then
break
fi
echo "你输入了: $INPUT"
done
# 方式一
while true; do
echo "执行中..."
sleep 1
done
# 方式二
while :; do
echo "执行中..."
sleep 1
done
# 方式三
while [ 1 ]; do
echo "执行中..."
sleep 1
done
# 等待服务启动
MAX_RETRY=10
COUNT=0
while [ $COUNT -lt $MAX_RETRY ]; do
if curl -s http://localhost:8080/health > /dev/null; then
echo "服务已启动"
break
fi
echo "等待服务启动... ($((COUNT+1))/$MAX_RETRY)"
sleep 2
COUNT=$((COUNT + 1))
done
if [ $COUNT -eq $MAX_RETRY ]; then
echo "服务启动超时"
exit 1
fi
# 逐行处理命令输出
ps aux | while read USER PID REST; do
if [ "$USER" = "root" ]; then
echo "root 进程: $PID"
fi
done
# 注意:管道后的 while 在子 Shell 中执行,变量不会保留
# 解决方案:用进程替换
while read LINE; do
VAR="value"
done < <(some_command)
echo $VAR # 可以访问
A=0
B=10
while [ $A -lt 5 ] && [ $B -gt 5 ]; do
echo "A=$A, B=$B"
A=$((A + 1))
B=$((B - 1))
done
I=1
while [ $I -le 3 ]; do
J=1
while [ $J -le 3 ]; do
echo "I=$I, J=$J"
J=$((J + 1))
done
I=$((I + 1))
done
监控脚本
#!/bin/bash
LOG_FILE="/var/log/app.log"
tail -f "$LOG_FILE" | while read LINE; do
if echo "$LINE" | grep -q "ERROR"; then
echo "发现错误: $LINE"
# 发送告警
fi
done
批量处理带进度
#!/bin/bash
FILES=(*.txt)
TOTAL=${#FILES[@]}
CURRENT=0
while [ $CURRENT -lt $TOTAL ]; do
FILE="${FILES[$CURRENT]}"
echo "处理 ($((CURRENT+1))/$TOTAL): $FILE"
# 处理逻辑
CURRENT=$((CURRENT + 1))
done
倒计时
#!/bin/bash
SECONDS=10
while [ $SECONDS -gt 0 ]; do
echo -ne "倒计时: $SECONDS 秒\r"
sleep 1
SECONDS=$((SECONDS - 1))
done
echo -e "\n时间到!"
重试机制
#!/bin/bash
MAX_RETRY=3
RETRY=0
while [ $RETRY -lt $MAX_RETRY ]; do
if ssh user@server "echo 连接成功"; then
break
fi
RETRY=$((RETRY + 1))
echo "连接失败,重试 $RETRY/$MAX_RETRY"
sleep 2
done
用 while 的场景:
用 for 的场景:
while 循环要点:
while readwhile true