介绍
shell 的 while 属于条件循环:条件为真,就一直循环;条件假,退出循环
一、基础语法
每次先执行条件表达式,返回 0(成功/真) 就进入 do 里面执行代码;非0(失败/假)跳出循环。
while 测试命令
do
命令1
命令2
done
重点:while 后面不是括号表达式,是一条命令,命令返回码 $? 决定循环是否继续。
最常用:
[ ](test命令)、[[ ]]增强判断,也可以直接放普通命令(如read)。
示例1:数字递增循环
#!/bin/bash
i=1
while [ $i -le 5 ] # i <=5
do
echo "i = $i"
i=$((i+1)) # 自增,不能漏!否则死循环
done
输出:
i = 1
i = 2
i = 3
i = 4
i = 5
⚠️ 坑:忘记修改循环变量 → 死循环,按
Ctrl + C终止。
二、while 条件写法分类
1. 使用 [ ](标准test,兼容所有sh)
while [ $i -gt 0 ]
do
echo $i
i=$((i-1))
done
2. [[ ]] bash增强版(推荐bash脚本)
支持正则、&& ||,不容易踩引号坑
while [[ $i -gt 0 && $name != "stop" ]]
do
...
done
3. 直接跟命令(非常常用!)
只要命令执行成功就循环。
# 每隔1秒打印时间,直到ctrl+c
while sleep 1
do
date
done
sleep 1 返回0,条件永远为真 → 死循环。
4. 无限死循环写法
两种等价写法:
# 写法1 true命令永远返回0
while true
do
echo "无限循环"
sleep 1
done
# 写法2 : 是空命令,返回0
while :
do
echo "无限循环"
sleep 1
done
三、while 读取文件(高频场景)
✅ 方式1:while read 逐行读文件(推荐)
#!/bin/bash
# 读取 test.txt 每一行,变量line保存每行内容
while read line
do
echo "行内容:$line"
done < test.txt
< test.txt是输入重定向,把文件作为read的标准输入。
带字段分割:读取多列文本
文件内容(user.txt)
zhangsan 20
lisi 25
wangwu 30
脚本:
while read name age
do
echo "姓名:$name,年龄:$age"
done < user.txt
read 默认按空白(空格/tab)分割,一行多个值依次赋值变量。
注意:
read默认会自动去掉行尾换行符;遇到\会换行续读,可加-r禁止反斜杠转义:while read -r line do echo "$line" done < test.txt
read -r写读取文件脚本的最佳实践,防止 \ 被解析为转义符
❗ 坑:管道方式 while 会开子shell
# 不推荐!管道 | 会开启子shell,循环内部修改的变量外部不生效
cat test.txt | while read line
do
count=$((count+1))
done
echo $count # count还是0!
原因:管道右边命令运行在子进程,变量无法回写到父shell。优先用输入重定向
<
四、循环控制
break:立刻跳出整个while循环,执行done后面代码continue:跳过本次循环剩余代码,直接进入下一轮条件判断
break
i=1
while [ $i -le 10 ]
do
if [ $i -eq 5 ];then
break # i=5 直接退出循环
fi
echo $i
i=$((i+1))
done
continue
i=0
while [ $i -lt 10 ]
do
i=$((i+1))
if [ $i -eq 5 ];then
continue # i=5,跳过echo,直接下一轮
fi
echo $i
done
# 输出1 2 3 4 6 7 8 9 10
break 可以加数字:
break 2跳出两层嵌套循环;continue同理continue 2
嵌套while示例
a=1
while [ $a -le 3 ]
do
b=1
while [ $b -le 3 ]
do
if [ $b -eq 2 ];then
break 2 # 一次性跳出内外两层while
fi
echo "a=$a b=$b"
b=$((b+1))
done
a=$((a+1))
done
五、输入重定向 & here-string / here-doc 配合while
Here-doc 给while传输入
while read name
do
echo "name: $name"
done <<EOF
Tom
Jack
Mary
EOF
Here-string
while read line
do
echo $line
done <<<"第一行
第二行"
六、while 与 until 的简单对比
while 条件:条件为真就循环until 条件:条件为假就循环i=1 until [ $i -gt 5 ] do echo $i i=$((i+1)) done
七、常见坑
- 变量比较:
[ ]前后必须空格,[$i -le 5]语法报错!要写[ $i -le 5 ] - 数字运算:
i=i+1是字符串拼接,必须i=$((i+1)) read不加-r,行里的\会被吃掉cat file | while read→ 子shell,变量失效,优先<重定向- 字符串比较,变量最好双引号包裹
[ "$var" = "abc" ],防止空值报错 - 死循环:
while true,终止快捷键Ctrl + C
八、练习题(可直接复制运行)
#!/bin/bash
# 计算1~10累加
sum=0
i=1
while [ $i -le 10 ]
do
sum=$((sum+i))
i=$((i+1))
done
echo "sum=$sum"
如果你需要,我可以再写:
- while读取csv、带IFS自定义分隔符的案例
- while监控进程/端口的运维脚本模板
- while的退出码、重定向异常处理详解