一、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编程实战 >