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