shell之while循环

本文介绍了在Shell脚本中使用while循环的基本语法和多种读取文件的方法,包括使用exec、cat以及输入重定向。通过示例展示了如何用while循环实现猜价格游戏以及从文件读取IP和port进行SSH操作的场景。

while循环

while循环是一种常见的循环结构,我们在学习python,C等编程语言时都接触过此结构。使用while循环,可以使得用户重复执行一系列操作,直到某个条件的发生。

while循环的基本语法

while expression
do
	statement1
	statement2
	...
done
    • 上述语法中,expression表示while循环语句执行时需要满足的条件。虽然此处可以使用任意合法的shell命令。但是通常情况下,expression代表一个测试表达式,与其他循环语句一样do和done关键字之间是循环结构的循环体。

1.while循环读取文件
方法一

    • 采用exec读取文件,然后进入while循环处理
exec < file
while read line
do
	statement1
done

方法二

    • 使用cat读取文件,然后通过管道进入while循环
cat file | while line
do
	statement
done

方法三

    • 通过在while循环结尾,使用输入重定向的方式
while read line
do
	statement
done < file

while语句的示例
案例一

    • 猜某一商品的价格
      要求: (1)通过变量random获取随机数
      (2)提示用户猜测并提示次数,猜中后退出循环
      分析: (1)如何产生随机数
      (2)猜中才会退出,需使用死循环(while true)
      (3)通过if语句,根据用户输入内容与随机数比较
      (4)记录猜测次数,每猜一次次数加一

示例代码

#! /bin/bash
  
PRICE=$[$RANDOM % 100 ] #生成一个两位数
TIMES=0
while true
do
        read -p "请输入商品的价格[0-99]:" var #用户输入猜测的价格
        let TIMES++          #猜测后,猜测次数加一
        if [ $var -eq $PRICE ]      #猜测价格与实际价格比较
        then
                echo "恭喜你,答对了!"
                echo "一共猜了$TIMES次!"
                exit 0      #猜对后,退出循环
        elif [ $var -gt $PRICE ]
        then
                echo "猜高了,请继续猜!!!"
        else
                echo "猜低了,请继续猜!!!"
        fi
done
结果:
[root@bogon ~]# ./while1.sh
请输入商品的价格[0-99]:50
猜低了,请继续猜!!!
请输入商品的价格[0-99]:75
猜高了,请继续猜!!!
请输入商品的价格[0-99]:65
猜高了,请继续猜!!!
请输入商品的价格[0-99]:58
猜低了,请继续猜!!!
请输入商品的价格[0-99]:63 
猜高了,请继续猜!!!
请输入商品的价格[0-99]:62      
猜高了,请继续猜!!!
请输入商品的价格[0-99]:59
猜低了,请继续猜!!!
请输入商品的价格[0-99]:60
猜低了,请继续猜!!!
请输入商品的价格[0-99]:61
恭喜你,答对了!
一共猜了9次!

while读取文件

要求:在生产环境中,要求从一个IP列表获取IP port,然后ssh ip 到目标机器进行特定的操作

模拟生产环境:先创建一个文件
示例代码

[root@bogon ~]vim file
192.168.150.111  222
192.168.150.112  333
192.168.150.113  444

方法一

#! /bin/bash
  
while read line
do
        IP=$(echo $line | awk {'print $1'})
        PORT=$(echo $line | awk {'print $2'})
        echo "IP: $IP,PORT: $PORT"
done < file
结果:
[root@bogon ~]# vim while2.sh
[root@bogon ~]# ./while2.sh 
IP: 192.168.150.111,PORT: 222
IP: 192.168.150.112,PORT: 333
IP: 192.168.150.113,PORT: 444

方法二

#! /bin/bash
exec < file
while read line
do
        IP=$(echo $line | awk {'print $1'})
        PORT=$(echo $line | awk {'print $2'})
        echo "IP: $IP,PORT: $PORT"
done

方法三

#! /bin/bash

cat file | while read line
do
        IP=$(echo $line | awk {'print $1'})
        PORT=$(echo $line | awk {'print $2'})
        echo "IP: $IP,PORT: $PORT"
done
<think>好的,用户现在想了解如何在Shell脚本中使用while循环。我需要根据他提供的引用内容以及之前的回答来组织一个清晰易懂的讲解。首先,用户提供的引用[1]、[2]、[3]、[4]中有多个示例,包括基本循环、无限循环、读取文件、条件判断等。我需要整合这些例子,同时参考之前关于进程通信的回答中的结构,比如使用代码块和分点说明。 首先,我应该从基础语法开始,说明while循环的基本结构,比如while后面跟条件,do和done之间的循环体。引用[1]和[2]中的例子都可以用来说明这一点,比如计数循环。 然后,用户可能需要了解不同的条件表达式写法,比如使用test命令的[ ],或者双括号(( )),这会影响条件的判断方式。引用[1]里的例子正好展示了两种不同的条件写法,可以对比说明。 接下来是无限循环的处理,用户可能想知道如何创建一直运行的循环,并在特定条件下退出。引用[1]中的无限循环使用冒号:作为条件,然后通过break退出,这需要解释清楚。同时,引用[4]中提到了break的使用,可以结合这个例子说明如何在循环中提前终止。 读取文件内容是一个常见用途,引用[1]和[2]都有读取文件的例子,特别是使用IFS=和read -r来处理每一行,避免空格或特殊字符的问题,需要强调这个最佳实践。 另外,用户提供的引用[3]中有一个跳过特定数字的例子,即排除7,这可以用来说明在循环内部使用条件判断(if语句)来控制流程,比如continue的使用。而引用[4]中的例子用到了break,可以对比说明continue和break的区别。 此外,用户之前的问题涉及到进程通信,虽然当前问题不直接相关,但可能需要保持回答的结构一致性,比如使用代码块和分点说明,确保清晰。同时,之前的回答中有方案对比表,可能在这里不太适用,但可以考虑用表格来总结不同条件写法的区别。 需要确保回答覆盖基本语法、不同条件写法、常见应用场景(如读取文件、无限循环)、流程控制(break和continue),以及实际示例。还要注意使用中文,并且按照用户的要求,行内公式用$...$,虽然这里可能用不上数学公式,但如果有变量或代码中的符号,可能需要处理。 最后,生成相关问题,比如如何避免无限循环、处理文件读取中的问题、循环中的条件判断等,帮助用户进一步学习。 检查是否有遗漏点,比如信号处理可能在之前的回答中提到过,但这里专注于循环,所以不需要涉及。确保每个部分都有对应的示例代码,并正确引用用户提供的引用内容,比如引用[1]到[4]中的例子,适当标注引用标记。</think>在Shell脚本中使用`while`循环的完整指南如下,结合基础语法、应用场景和实战技巧: --- ### 一、基础语法结构 ```bash while 条件表达式 do # 循环体 执行命令 done ``` --- ### 二、5种核心用法详解 #### 1. 基础数字循环 **需求**:循环输出1-10的数字 ```bash # 使用 [ ] 条件判断(传统test命令) i=1 while [ $i -le 10 ] do echo $i i=$((i+1)) # 或 ((i++)) done # 使用 (( )) 算术扩展(推荐) j=1 while ((j <= 10)) do echo $j ((j++)) # 更简洁的语法 done ``` *两种方式的区别*: - `[ ]`需要严格空格和转义符号 - `(( ))`支持更自然的数学表达式[^1][^2] --- #### 2. 无限循环实现 **场景**:需要持续运行的监控程序 ```bash # 三种实现方式 # 方式1:使用特殊符号: while : do echo "持续运行中..." sleep 1 done # 方式2:直接使用true命令 while true do echo "服务监控中..." sleep 5 done # 方式3:空条件判断 while [ 1 ] do echo "系统检测..." sleep 2 done ``` *中断技巧*:使用`Ctrl+C`或设置`break`条件[^1][^4] --- #### 3. 文件逐行处理 **需求**:读取`data.txt`并处理每行内容 ```bash # 标准写法(处理特殊字符) while IFS= read -r line do echo "处理内容: $line" # 添加其他处理逻辑 done < data.txt ``` *关键参数说明*: - `IFS=`:防止前导/尾随空格被截断 - `-r`:禁止反斜杠转义[^1][^2] --- #### 4. 条件过滤控制 **案例**:输出1-10之间不等于7的数字 ```bash i=1 while ((i <= 10)) do if ((i == 7)); then ((i++)) continue # 跳过当前循环 fi echo $i ((i++)) done ``` *流程控制语句*: - `continue`:跳过当前迭代 - `break`:立即终止循环[^3][^4] --- #### 5. 命令结果判断 **场景**:持续检测网络连通性 ```bash # 当能ping通时持续输出 while ping -c1 google.com &>/dev/null do echo "$(date): 网络正常" sleep 10 done echo "网络连接丢失!" ``` *特性*:循环条件可以是任意命令的退出状态码(0为真,非0为假) --- ### 三、高级技巧 #### 1. 嵌套循环 ```bash while read host; do while read port; do nc -zv $host $port done < ports.txt done < hosts.txt ``` #### 2. 并发控制 ```bash max_workers=5 task_queue=(task1 task2 task3 task4 task5 task6) while (( ${#task_queue[@]} > 0 )); do running=$(jobs -r | wc -l) if (( running < max_workers )); then task=${task_queue[0]} task_queue=("${task_queue[@]:1}") ( echo "开始执行 $task" sleep $((RANDOM%5+1)) echo "完成 $task" ) & fi sleep 0.1 done wait ``` --- ### 四、调试技巧 1. 使用`-x`参数追踪执行: ```bash bash -x script.sh ``` 2. 插入调试语句: ```bash while condition; do echo "DEBUG: 当前变量值=$var" # ... done ``` --- ### 五、常见错误排查表 | 错误现象 | 原因分析 | 解决方案 | |--------------------------|--------------------------|-----------------------------| | 循环无法启动 | 条件表达式语法错误 | 检查`[ ]`的空格和运算符 | | 无限循环无法终止 | 缺少退出条件 | 添加`break`或条件变量更新 | | 文件内容截断 | 未设置`IFS=`和`-r`参数 | 使用`while IFS= read -r`结构 | | 变量值未更新 | 子shell作用域问题 | 避免在管道中创建子shell | | 特殊字符处理异常 | 未正确转义 | 使用双引号包裹变量`"$var"` | [^1]: Shell脚本while循环基础语法 [^2]: 文件读取与条件判断示例 [^3]: 循环控制语句应用案例 [^4]: 流程中断与继续操作 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值