本文主要讲解 Shell 脚本开发中 while 和 until 循环的知识与实践
基本大纲:
1. 当型和直到型循环语法
2. 当型和直到型循环的基本范例
3.shell 脚本在后台运行的知识
4.while 循环按行读文件的方式总结
5.while 循环语句生产实践
一: 当型和直到型循环语法
循环语句命令常用于重复执行一条指令或一组指令, 直到条件不再满足时停止, Shell 脚本语言的循环语句常见的有 while,until,for, 及 select 循环语句.
while 循环语句主要用来重复执行一组命令或语句, 在企业实际应用中, 常用于守护进程或持续运行的程序.
1.while 循环语句的基本语法为:
while <条件表达式>
do
指令...
done
注: while 循环语句会对紧跟在 while 命令后的条件表达式进行判断, 如果该条件表达式成立, 则执行 while 循环体里的命令或语句 (即语法中 do 和 done 之间的指令), 每一次执行到 done 时就会重新判断 while 条件表达式是否成立, 知道条件表达式不成立时才会跳出 while 循环体. 如果一开始条件表达式就不成立, 那么程序就不会进入循环体(即语法中 do 和 done 之间的部分) 中执行命令了.
2.until 循环语句的语法为:
until <条件表达式>
do
指令...
done
注: until 循环语句的用法与 while 循环语句的用法类似, 区别是 until 会在条件表达式不成立时, 进入循环执行指令; 条件表达式成立时, 终止循环.
二: 当型和直到型循环的基本范例
范例 1: 每隔 5 秒输出一次系统负载 (负载是系统性能的基础重要指标) 情况.
- [root@aliyun xh]# cat while.sh
- #!/bin/bash
- while true #while true 表示条件永远为真, 因此会一直运行, 像死循环一样, 我们称之为守护进程
- do
- uptime
- sleep 5 #休息 5 秒后继续循环, 控制循环的频率
- done
- [root@aliyun xh]# sh while.sh
04:00:01 up 52 days, 5:44, 2 users, load average: 0.64, 0.75, 1.83
04:00:06 up 52 days, 5:45, 2 users, load average: 0.67, 0.75, 1.83
范例 2: 将负载值追加到文件里
- [root@aliyun xh]# cat while.sh
- #!/bin/bash
- while [ 1 ] #注意 [ ] 里面两端要有空格, true 和 1 都表示条件永远成立
- do
- uptime >>/tmp/uptime.log #将负载值输入到 log 文件里
- usleep 5000000 #单位为微秒, 其实就是 5 秒
- done
- [root@aliyun xh]# sh while.sh &
- [1] 15782
- [root@aliyun xh]# tailf /tmp/uptime.log #使用 tailf 命令实时观察输出结果
04:10:37 up 52 days, 5:55, 2 users, load average: 0.60, 0.63, 1.22
04:10:42 up 52 days, 5:55, 2 users, load average: 0.63, 0.64, 1.22
04:10:47 up 52 days, 5:55, 2 users, load average: 0.90, 0.69, 1.23
04:10:52 up 52 days, 5:55, 2 users, load average: 0.91, 0.70, 1.23
范例 3: 计算从 1 加到 100 之和(用 1+2+3+...+100 的方法)
- [root@aliyun xh]# cat jisuan.sh
- #!/bin/bash
- i=1
- sum=0
- while ((i<=100))
- do
- ((sum=sum+i))
- ((i++))
- done
- [ "$sum" -ne 0 ] && printf "totalsum is: ${sum}\n"
- [root@aliyun xh]# sh jisuan.sh
- totalsum is: 5050
法二:
- [root@aliyun xh]# cat test2.sh
- #!/bin/bash
- i=100
- ((sum=i*(i+1)/2))
- printf "totalsum is: ${sum}\n
范例 4: 使用 until 命令实现循环竖向打印 54321
- [root@aliyun xh]# cat until.sh
- #!/bin/bash
- i=5
- until [[ $i < 1 ]] #当条件表达式不成立时, 进入循环执行命令. 5<1 不成立, 所以进入循环
- do
- echo $i
- ((i--))
- done
- [root@aliyun xh]# sh until.sh
- 5
- 4
- 3
- 2
- 1
三: shell 脚本在后台运行的知识
sh while.sh & : 把脚本 while.sh 放到后台执行(常用方法)
ctrl+c : 停止执行当前脚本或任务
ctrl+z : 暂停执行当前脚本或任务
bg : 把当前脚本或任务放到后台执行
fg : 把当前脚本或任务放到前台执行, 如果有多个任务的话, 可以使用 fg 加任务编号调出对应的脚本任务. 如 fg 2, 是指调出第二个脚本任务
jobs : 查看当前执行的脚本或任务
kill : 关闭执行的脚本任务, 即以 "kill % 任务编号" 的形式关闭脚本, 这个任务编号, 可以通过 jobs 来获得
- [root@aliyun xh]# sh while.sh & #结尾使用 & 符号表示在后台运行脚本
- [1] 20994
- [root@aliyun xh]# fg #执行 fg 命令将脚本放到前台执行
- sh while.sh
- ^Z #临时暂停执行脚本
[1]+ Stopped sh while.sh
[root@aliyun xh]# bg #将当前执行的脚本放到后台运行
[1]+ sh while.sh &
[root@aliyun xh]# jobs #查看当前 shell 下运行的脚本任务
[1]+ Running sh while.sh &
- [root@aliyun xh]# fg 1 #可以使用 fg 加 jobs 输出中的任务编号调出对应编号的脚本到前台来运行
- sh while.sh
- ^C #当脚本在前台运行时, 可以执行 ctrl+c 快捷键停止脚本运行
- # 下面是使用 kill 命令关闭 jobs 任务脚本的示例
- [root@aliyun xh]# jobs
[1]- Running sh while.sh &
[2]+ Running sh while.sh &
- [root@aliyun xh]# kill %2 #注意任务编号的写法
- [root@aliyun xh]# jobs
[1]- Running sh while.sh &
[2]+ Terminated sh while.sh #表示脚本已关闭
四: while 循环按行读文件的方式总结
方式 1: 采用 exec 读取文件, 然后进入 while 循环处理
- exec < file
- sum=0
- while read line
- do
- cmd
- done
方式 2: 使用 cat 读取文件内容, 然后通过管道进入 while 循环处理
- cat file_path | while read line
- do
- cmd
- done
方式 3: 在 while 循环结尾 done 处通过输入重定向指定读取的文件
- while read line
- do
- cmd
- done < file
范例: 开发一个 Shell 脚本实现 linux 系统命令 cat 读文件的基本功能
- [root@aliyun xh]# cat cat.sh
- #!/bin/bash
- while read line
- do
- echo $line
- done < $1
- [root@aliyun xh]# sh cat.sh nohup.out
03:44:15 up 52 days, 5:29, 2 users, load average: 0.74, 2.47, 3.93
03:44:17 up 52 days, 5:29, 2 users, load average: 0.68, 2.43, 3.91
03:44:19 up 52 days, 5:29, 2 users, load average: 0.68, 2.43, 3.91
五: while 循环语句生产实践
范例: 使用 while 守护进程的方式监控网站, 每隔 10 秒确定一次网站是否正常.
- [root@aliyun xh]# cat whilesc.sh
- #!/bin/bash
- . /etc/init.d/functions #引入函数库
- if [ $# -ne 1 ] #判断脚本参数
- then
- echo $"usage $o URL"
- exit 1
- fi
- while true
- do
- if [ `curl -o /dev/null --connect-timeout 5 -s -w "%{http_code}" $1|egrep -w "200|301|302" | wc -l` -ne 1 ] #判断 http 状态值
- then
- action "$1 is error" /bin/false #优雅显示
- else
- action "$1 is ok" /bin/true
- fi
- sleep 10
- done
- [root@aliyun xh]# sh whilesc.sh baidu.com
baidu.com is ok [ OK ]
baidu.com is ok [ OK ]
- [root@aliyun xh]# sh whilesc.sh baidusds.com
- baidusds.com is error [FAILED]
- baidusds.com is error [FAILED]
来源: http://www.bubuko.com/infodetail-2635940.html