while循环、break、continue、exit

一 while循环

语法 while 条件; do … ; done
案例1:每隔30s检查下系统负载,当系统负载大于10,就发送邮件

分析:如果不用while循环,我们只能使用任务计划cron,但这样的最小时间是1分钟,达不到隔30s检查一次的要求

#!/bin/bash
while :   //这里的:冒号可以用true代替,写的是死循环
do
    load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1`  //给负载load赋值
    if [ $load -gt 10 ]
    then
        top|mail -s "load is high: $load" [email protected]
    fi
    sleep 30
done

像这种死循环的脚本,为了不让他意外的终止,我们可以打开一个screen来运行他
我们来解析下上面案例中的命令w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1

[root@lijie-01 ~]# w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1
0
[root@lijie-01 ~]# w         //查看负载
 06:56:07 up 13:59,  2 users,  load average: 0.05, 0.03, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.75.1     04:52   10:39   0.66s  0.40s vim while.sh
root     pts/2    192.168.75.1     05:57    7.00s  0.10s  0.00s w
[root@lijie-01 ~]# uptime   //截取负载信息的第一行
 06:56:12 up 13:59,  2 users,  load average: 0.04, 0.03, 0.05
[root@lijie-01 ~]# w|head -1    //效果等同于上面一条命令
 07:04:21 up 14:07,  2 users,  load average: 0.00, 0.01, 0.05
[root@lijie-01 ~]# uptime|awk -F 'load average:' '{print $2}'   //以load average:作为分隔符截取负载信息第一行的第二段
 0.02, 0.02, 0.05
[root@lijie-01 ~]# uptime|awk -F 'load average:' '{print $2}'|cut -d. -f1   //再以.作为分隔符截取第一段
 0
[root@lijie-01 ~]# uptime|awk -F 'load average: ' '{print $2}'|cut -d. -f1   //load average: 后面加上空格以去掉上面一条命令运行结果前面的0
0
[root@lijie-01 ~]# uptime|awk -F 'load average:' '{print $2}'|cut -d. -f1|sed 's/ //'   //也可以再用 sed 's/ //'过滤一次以去掉上面一条命令运行结果前面的0
0

我们还可以写成

#!/bin/bash
while true
do
   load='w|head -1|awk -F `load average: ` `{print $2}` |cut -d. -f1'
   if [ $load -gt 10 ]
   then
     /usr/lib/zabbix/alertscripts/mail.py [email protected] "load high" " $load"
   fi
   sleep 30
done

运行结果出错

[root@lijie-01 shell]# sh while.sh
while.sh: 第 5 行:[: 参数太多

我们来排查错误,发现load赋值语句的引号有问题,修改后提示以下错误

[root@lijie-01 shell]# sh while.sh
while.sh:行4: average:: 未找到命令
while.sh: 第 5 行:[: -gt: 期待一元表达式
^[while.sh:行4: average:: 未找到命令
while.sh: 第 5 行:[: -gt: 期待一元表达式
while.sh:行4: average:: 未找到命令
while.sh: 第 5 行:[: -gt: 期待一元表达式

结果发现load赋值语句是系统命令,最外层应该使用反引号,修改后再运行,由于我们写的是死循环,因此脚本处于一直运行的状态,如下:

[root@lijie-01 shell]# sh while.sh

为了能更明显的观察到现象,我们将脚本修改为当负载小于10发送邮件

[root@lijie-01 shell]# cat !$
cat while.sh
#!/bin/bash
while :
do
   load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1`
   if [ $load -lt 10 ]
   then
     /usr/lib/zabbix/alertscripts/mail.py [email protected] "load high" " $load"
   fi
   exit
done

过了30s后,就正常收到邮件了
while循环案例2:做一个让用户不停输入我们想要东西的脚本

[root@lijie-01 shell]# cat !$
cat while2.sh
#!/bin/bash
while :
do 
  read -p "Please input a number: " n
     if [ -z "$n" ]
     then
        echo "你还没有输入的,请输入!"
        continue
     fi
     n1=`echo $n|sed 's/[0-9]//g'`
     if [ ! -z "$n1" ]
     then
        echo "你需要输入一个纯数字!"
        continue
     fi
     break
done
echo $n

下面来执行

[root@lijie-01 shell]# sh -x while2.sh
+ :
+ read -p 'Please input a number: ' n
Please input a number: 
+ '[' -z '' ']'
+ echo '你还没有输入的,请输入!'
你还没有输入的,请输入!
+ continue
+ :
+ read -p 'Please input a number: ' n
Please input a number: 12324dfff
+ '[' -z 12324dfff ']'
++ sed 's/[0-9]//g'
++ echo 12324dfff
+ n1=dfff
+ '[' '!' -z dfff ']'
+ echo '你需要输入一个纯数字'
你需要输入一个纯数字
+ continue
+ :
+ read -p 'Please input a number: ' n
Please input a number: 3425
+ '[' -z 3425 ']'
++ sed 's/[0-9]//g'
++ echo 3425
+ n1=
+ '[' '!' -z '' ']'
+ break
+ echo 3425
3425
[root@lijie-01 shell]#

二 break跳出循环

break用于循环语句中

#!/bin/bash 
for i in `seq 1 5`
do
    echo $i
    if [ $i == 3 ]     //如果是数字间的比较,可以使用-eq;如果比较的对象包含数字外的其他字符,则必须要使用==来比较
    then
        break
    fi
    echo $i
done
echo abc

执行过程如下:

[root@lijie-01 shell]# sh -x break.sh
++ seq 1 5
+ for i in '`seq 1 5`'
+ echo 1
1
+ '[' 1 == 3 ']'
+ for i in '`seq 1 5`'
+ echo 2
2
+ '[' 2 == 3 ']'
+ for i in '`seq 1 5`'
+ echo 3
3
+ '[' 3 == 3 ']'
+ break
+ echo abc
abc
[root@lijie-01 shell]#

三 continue结束本次循环

忽略continue之下的代码,直接进行下一次循环

#!/bin/bash 
for i in `seq 1 5`
do
    echo $i
    if [ $i == 3 ]    
    then
        continue   //当i=3时,跳出本次循环
    fi
    echo $i
done
echo abc

执行过程如下:

[root@lijie-01 shell]# sh continue.sh 
1
1
2
2
3
4
4
5
5
abc
[root@lijie-01 shell]#

四 exit退出整个脚本

[root@lijie-01 shell]# cat !$
cat exit.sh
#!/bin/bash
for i in `seq 1 5`
do 
  echo $i
  if [ $i == 3 ]
  then
    exit 2
  fi
  echo $i
done
echo abc
[root@lijie-01 shell]# sh exit.sh 
1
1
2
2
3
[root@lijie-01 shell]# echo $?
2
[root@lijie-01 shell]#

猜你喜欢

转载自my.oschina.net/u/3746774/blog/1798214