shell 学习笔记9-while/until循环语句

一、while循环语句

  1、循环语句

    循环愈久就是重复执行一条指令或一组执行,知道条件不在满足时停止,shell循环语句包括,while、until、for、select语句

  2、while循环

    主要用来重复执行命令或语句,常用来守护进程或持续运行的程序,其实大多数循环都会用for循环语句

  3、语法

while <条件表达式>
do
    指令...
done

   4、流程图

二、until循环语句

  1、until循环语句语法

until <条件表达式>
do
    指令...
done

  until 循环语句用法与while类似,只是until会在表达式不成立时,进入循环执行命令,表达式成立,终止循环,until应用场景非常罕见

三、知识补充

  1、当型和直型循环的范例

    shell中有两个休息命令:sleep 1 表示休息1秒,usleep 1000000 也表示休息1秒

    1)每隔2秒输出一次系统负载

[root@web1 scripts]# ./test
test10.sh    test14.sh    test19.sh    test22.sh    test27.sh    test31.sh    test36.sh    test7.sh
test11.sh    test15.sh    test1.sh     test23.sh    test28.sh    test32.sh    test3.sh     test8.sh
test12-1.sh  test16.sh    test20.sh    test24.sh    test29.sh    test33.sh    test4.sh     test9.sh
test12.sh    test17.sh    test21-1.sh  test25.sh    test2.sh     test34.sh    test5.sh     
test13.sh    test18.sh    test21.sh    test26.sh    test30.sh    test35.sh    test6.sh     
[root@web1 scripts]# cat test36.sh
#!/bin/bash
while true            #while true 表示条件永远为真,就像是死循环一样,我们称为守护进程
do
        uptime        
        sleep 2         #休息2秒,在继续循环,while true循环中最好添加类似sleep的命令,可以控制脚本频率,省资源,不然真成死循环了
done
[root@web1 scripts]# ./test36.sh 
 12:26:45 up 10 days,  1:50,  3 users,  load average: 0.00, 0.01, 0.05
 12:26:47 up 10 days,  1:50,  3 users,  load average: 0.00, 0.01, 0.05
 12:26:49 up 10 days,  1:51,  3 users,  load average: 0.00, 0.01, 0.05

    2)每隔2秒在屏幕上输出一次负载并将负载值追加到log里,使用微秒单位

[root@web1 scripts]# cat test37.sh 
#!/bin/bash
while [ 1 ]
do
        uptime >>/tmp/uptime.log
        usleep 2000000
done
[root@web1 scripts]# ./test37.sh
^C
[root@web1 scripts]# cat /tmp/uptime.log 
 12:31:41 up 10 days,  1:55,  3 users,  load average: 0.00, 0.01, 0.05
 12:31:43 up 10 days,  1:55,  3 users,  load average: 0.00, 0.01, 0.05
 12:31:45 up 10 days,  1:55,  3 users,  load average: 0.00, 0.01, 0.05
 12:31:47 up 10 days,  1:55,  3 users,  load average: 0.00, 0.01, 0.05
 12:31:49 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:31:51 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:31:53 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:31:55 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:31:57 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:31:59 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:32:01 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:32:03 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:32:05 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:32:07 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:32:09 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:32:11 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05
 12:32:13 up 10 days,  1:56,  3 users,  load average: 0.00, 0.01, 0.05

    3)通过结尾使用&符合后台运行脚本

[root@web1 scripts]# ./test37.sh &
[1] 19536
[root@web1 scripts]# tail -f /tmp/uptime.log
 12:46:07 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05
 12:46:09 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05
 12:46:11 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05
 12:46:14 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05
 12:46:16 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05
 12:46:18 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05
 12:46:20 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05
 12:46:22 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05
 12:46:24 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05
 12:46:26 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05
 12:46:28 up 10 days,  2:10,  3 users,  load average: 0.00, 0.01, 0.05

  2、shell脚本后台运行的知识补充

    1)用法及说明

 

 

 

[root@web1 scripts]# ./test37.sh &        #后台运行脚本
[2] 32970
[1]   Terminated              ./test37.sh
[root@web1 scripts]# fg           #将脚本放到前台执行,如果多脚本任务,可以使用fg加jobs输出的任务编号调出相应的脚本到前台
./test37.sh
^Z                        #使用ctrl+z快捷键,暂停脚本
[2]+  Stopped                 ./test37.sh
[root@web1 scripts]# bg            #bg,将当前执行的脚本放到后台运行
[2]+ ./test37.sh &
[root@web1 scripts]# jobs          #查看任务
[2]+  Running                 ./test37.sh &       

[root@web1 scripts]# fg 2          #fg加jobs输出的任务号调出脚本到前台来运行
./test37.sh
^C
[root@web1 scripts]# jobs          
[root@web1 scripts]# ./test37.sh &
[1] 33054
[root@web1 scripts]# jobs
[1]+  Running                 ./test37.sh &
[root@web1 scripts]# kill %1        #kill 命令关闭jobs任务脚本
[root@web1 scripts]# jobs
[1]+  Terminated              ./test37.sh
[root@web1 scripts]# 

四、范例

  1、使用while循环竖向打印54321

[root@web1 scripts]# cat test38.sh
#!/bin/bash
i=5                        #因为是从大到小,所以初始化i的值为5
while ((i>0))                  #双小括号条件表达式,当i大于0不成立时就跳出循环
do 
        echo "$i"                #打印变量i的值
        ((i--))                 #i的值自减,每次减1
done

[root@web1 scripts]# ./test38.sh 
5
4
3
2
1
[root@web1 scripts]# 

  2、使用双中括号条件表达式

[root@web1 while-until]# cat test39.sh 
#!/bin/bash
i=5
while [[ $i > 0 ]]
do
        echo $i
        ((i--))
done

[root@web1 while-until]# ./test39.sh 
5
4
3
2
1
[root@web1 while-until]# 

  3、使用传参需要打印的数字

[root@web1 while-until]# cat test40.sh 
#!/bin/bash

i="$1"
while [[ $i -gt 0 ]]
do 
        echo $i
        ((i--))
done

[root@web1 while-until]# ./test40.sh  5
5
4
3
2
1
[root@web1 while-until]# 

  4、使用until语句实现

[root@web1 while-until]# cat test41.sh
#!/bin/bash
i=5
until [[ $i < 1 ]]        #当条件表达式不成立时,进入循环执行命令,因为0<1成立,因此退出循环
do
        echo $i
        ((i--))
done
[root@web1 while-until]# ./test41.sh  
5
4
3
2
1
[root@web1 while-until]# 

  5、计算1加到100之和

[root@web1 while-until]# cat test42.sh 
#!/bin/bash
i=1                             #i为自增变量,从1到100,初始值1
sum=0                            #总和变量初始值为0
while ((i<=100))                     #条件是i小于等于100,也就是从1加到100
do
        ((sum=sum+i))                  #把i的值和当前sum总和的值做加法结果重新赋值给sum
        ((i++))                      #i每次加1
done
[ "$sum" -ne 0 ] && printf "totalsum is:$sum\n"
 
[root@web1 while-until]# ./test42.sh 
totalsum is:5050
[root@web1 while-until]# 

  6、通过数学公式实现

[root@web1 while-until]# cat 4-6.sh 
#!/bin/bash
i=100
((sum=i*(i+1)/2))              #利用数公式求和公式计算,效率很高
echo $sum

[root@web1 while-until]# ./4-6.sh 
5050

  7、猜数字游戏

 

#!/bin/bash
total=0
export LANG="zh_CN.UTF-8"
NUM=$((RANDOM%61))
echo "当前苹果价格是每斤$NUM元"
echo "========================"
usleep 1000000
clear
echo '这苹果多少钱一斤啊?
      请猜0-60的数字'
apple(){
read -p "请输入你的价格:" PRICE
expr $PRICE + 1 &>/dev/null
if [ $? -ne 0 ]
 then
        echo "别逗我了,快猜数字"
        apple
fi
}

guess(){
        ((total++))
        if [ $PRICE -eq $NUM ]
         then
                echo "猜对了,就是$NUM元"
                if [ $total -le 3 ];then
                   echo "一共猜了$total次,太牛了。"
                elif [ $total -gt 3 -a $total -le 6 ];then
                   echo "一共猜了$total次,次数有点多,加油啊。"
                elif [ $total -gt 6 ];then
                   echo "一共猜了$total次,行不行,猜了这多次"
                fi
                exit 0
         elif [ $PRICE -gt $NUM ]
          then
                echo "嘿嘿,要不你用这个价买?"
                echo "再给你一次机会,请继续猜:"
                apple
         elif [ $PRICE -lt $NUM ]
          then
                echo "太低太低"
                echo "再给你一次机会,请继续猜:"
                apple
         fi
}
main(){
apple
while true
do
  guess
done
}
main



  8、手机充值

    手机充值10元,每发一次短信(输出当前余额)花费1角5分钱,当余额地域1角5分钱时就不能再发短信了,提示余额不足,请重置,充值后可以继续发短信

[root@oldboy C11]# cat 10_5_1.sh
#!/bin/sh
export LANG="zh_CN.UTF-8"
sum=15
msg_fee=15
msg_count=0
menu(){
    cat <<END
当前余额为${sum}分,每条短信需要${msg_fee}分
==========================
      1.充值
      2.发消息
      3.退出
==========================
END
}
recharge(){
    read -p "请输入金额充值:" money
        expr $money + 1 &>/dev/null 
        if [ $? -ne 0 ]
           then
               echo "then money your input is error,must be int."
           else 
               sum=$(($sum+$money))
               echo "当前余额为:$sum"
        fi
}
sendInfo(){
    if [ ${sum} -lt $msg_fee ]
       then
            printf "余额不足:$sum ,请充值。\n"
       else 
            while true 
              do
                 read -p "请输入短信内容(不能有空格):" msg
                 sum=$(($sum-$msg_fee))
                 printf "Send "$msg" successfully!\n"
                 printf "当前余额为: $sum\n"
                 if [ $sum -lt 15 ]
                    then
                        printf "余额不足,剩余$sum分\n"
                        return 
                 fi
            done
    fi
}
main(){
while true
do
   menu
   read -p "请输入数字选择:" num
   case "$num" in
       1)
         recharge
         ;;
       2)
         sendInfo
         ;;
       3)
         exit 
         ;;
       *)
        printf "选择错误,必须是{1|2|3}\n"
   esac
done
}
main

  9、使用while守护进程的方式监控网站,每隔10s确定一次网站是否正常

#!/bin/sh
if [ $# -ne 1 ];then
   echo $"usage $0 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 ]
     then
      echo "$1 is error."
      #echo "$1 is error."|mail -s "$1 is error." 31333741--@qq.com
   else
      echo "$1 is ok"
   fi
   sleep 10
done
[root@web1 while-until]# ./4-9.sh 
usage ./4-9.sh url
[root@web1 while-until]# ./4-9.sh www.baidu.com 
www.baidu.com is ok
^C
[root@web1 while-until]# ./4-9.sh www.baidu1111.com 
www.baidu1111.com is ok
^C
[root@web1 while-until]# ./4-9.sh www.111baidu1111.com 
www.111baidu1111.com is error.
^C
[root@web1 while-until]# 

 

 

参考学习引用:https://blog.51cto.com/oldboy/1855442

参考学习图书:<跟老男孩学linux运维:shell编程实战 >

转载请注明出处:https://www.cnblogs.com/zhangxingeng/p/11412371.html 

posted @ 2019-09-09 17:42  乐章  阅读(589)  评论(0编辑  收藏  举报