本文主要讲解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]