一、当型和直到型循环

1.while循环语句

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

while循环执行流程对应的逻辑图

2.until循环语句

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

until会在条件表达式不成立时,进入循环体执行指令。

3.基本范例

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

[root@codis-178 ~]# cat 10_1.sh
#!/bin/bash
while true
do
uptime
sleep 2
done
[root@codis-178 ~]# sh 10_1.sh
13:59:41 up 251 days, 22:33, 1 user, load average: 0.02, 0.03, 0.00
13:59:43 up 251 days, 22:33, 1 user, load average: 0.02, 0.03, 0.00
13:59:45 up 251 days, 22:33, 1 user, load average: 0.02, 0.03, 0.00
13:59:47 up 251 days, 22:33, 1 user, load average: 0.02, 0.03, 0.00

(2)防止脚本执行中断的办法

1)使用&,在后台运行

2)使用nohup加&,在后台运行

3)利用screen保持会话,然后再执行命令或脚本

补充;

strace:跟踪一个进程的系统调用情况

ltrace:跟踪进程调用库函数的情况

(3)while循环竖向打印54321

[root@codis-178 ~]# cat 10_2.sh
#!/bin/bash
i=5
while ((i>0))
do
echo "$i"
((i--))
done
[root@codis-178 ~]# sh 10_2.sh
5
4
3
2
1

(4)计算1加到100之和

[root@codis-178 ~]# cat 10_3.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@codis-178 ~]# sh 10_3.sh
totalsum is:5050

(5)猜数字,系统随机生成一个数字(1~60),让用户输入所猜数字,判断是否正确

[root@codis-178 ~]# cat 10_4.sh
#!/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 "猜对了"
if [ $total -le 3 ];then
echo "已经猜 $total 次了!"
elif [ $total -gt 3 -a $toatl -le 6 ];then
echo "已经猜 $total 次了!"
elif [ $total -gt 6 ];then
echo "已经猜 $total 次了!有点多!"
fi
exit 0
elif [ $PRICE -gt $NUM ];then
echo "猜高了!"
apple
elif [ $PRICE -lt $NUM ];then
echo "猜低了!"
apple
fi
}
main(){
apple
while true
do
guess
done
}
main [root@codis-178 ~]# sh 10_4.sh
当前苹果的价格是每斤 30 元
============================
这苹果多少钱一斤啊?请猜0~60的数字
请输入你的价格:40
猜高了!
请输入你的价格:25
猜低了!
请输入你的价格:30
猜对了
已经猜 3 次了!

(6)手机充值10元,每发一条短信花费1.5元,当余额低于1.5元时不能再发短信

[root@codis-178 ~]# cat 10_5.sh
#!/bin/bash
export LANG="zh_CN.UTF-8"
sum=15
msg_fee=2
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 "发送 $msg successfully!\n"
printf "当前余额:$sum\n"
if [ $sum -lt $msg_fee ];then
printf "余额不足,剩余 $sum分\n"
return 1
fi
done
fi
} main(){
while true
do
menu
read -p "请输入数字选择:" men
case "$men" in
1)
recharge
;;
2)
sendInfo
;;
3)
exit 1
;;
*)
printf "选择错误,必须是{1|2|3}\n"
esac
done
}
main

4.企业应用

(1)监控网站,每隔10秒确定一次网站是否正常

[root@codis-178 ~]# cat 10_6.sh
#!/bin/bash
. /etc/init.d/functions
check_count=0
url_list=(
http://www.baidu.com
http://www.anzhi.com
http://www.163.com
)
function wait(){
echo -n '3秒后,执行检查URL操作。';
for ((i=0;i<3;i++))
do
echo -n ".";sleep 1
done
echo
}
function check_url(){
wait
for ((i=0; i<`echo ${#url_list[*]}`; i++))
do
wget -o /dev/null -T 3 --tries=1 --spider ${url_list[$i]} >/dev/null 2>&1
if [ $? -eq 0 ];then
action "${url_list[$i]}" /bin/true
else
action "${url_list[$i]}" /bin/false
fi
done
((check_count++))
}
main(){
while true
do
check_url
echo "-------check count:${check_count}--------"
sleep 5
done
}
main [root@codis-178 ~]# sh 10_6.sh
3秒后,执行检查URL操作。...
http://www.baidu.com [ OK ]
http://www.anzhi.com [ OK ]
http://www.163.com [ OK ]
-------check count:1--------
3秒后,执行检查URL操作。...
http://www.baidu.com [ OK ]
http://www.anzhi.com [ OK ]
http://www.163.com [ OK ]
-------check count:2--------

(2)分析Apache日志,把日志中每行的访问字节数对应的字段数字相加,计算总的访问量。

[root@codis-178 ~]# cat 10_7.sh
#!/bin/bash
sum=0
exec <$1 #将参数$1输入重定向给exec
while read line
do
size=`echo $line|awk '{print $10}'`
expr $size + 1 &>/dev/null
if [ $? -ne 0 ];then
continue
fi
((sum=sum+$size))
done
echo "${1}:total:${sum}bytes = `echo $((${sum}/1024))`KB}"

一条命令完成

awk '{print $10}' access.log |grep -v "-"|awk '{sum+=$1}END{print sum}'

5.按行读文件的方法总结

(1)exec

exec <FILE
sum=0
while read line
do
cmd
done

(2)cat

cat FILE|while read line
do
cmd
done

(3)在while循环结尾

while read line
do
cmd
done < FILE

6.实战应用

根据Web日志或系统网络连接数,监控某个IP的并发连接数,若短时间内PV达到100,即调用防火墙命令封掉对应的IP。

(1)按日志分析

[root@codis-178 ~]# cat 10_8.sh
#!/bin/bash
file=$1
while true
do
awk '{print $1}' $1|grep -v "^$"|sort|uniq -c > /tmp/tmp.log
exec </tmp/tmp.log
while read line
do
ip=`echo $line|awk '{print $2}'`
count=`echo $line|awk '{print $1}'`
if [ $count -gt 500 ] && [ `iptables -L -n|grep "$ip"|wc -l` -lt 1 ];then
iptables -I INPUT -s $ip -j DROP
echo "$line is dropped" >>/tmp/droplist_$(date +%F).log
fi
done
sleep 10
done

(2)按TCP请求

[root@codis-178 ~]# cat 10_9.sh
#!/bin/bash
file=$1
JudgeExt(){
if expr "$1" : ".*\.log" &>/dev/null
then
:
else
echo $"usage:$0 xxx.log"
exit 1
fi
}
IpCount(){
grep "ESTABLISHED" $1 |awk -F "[ :]+" '{ ++S[$(NF-3)]}END {for(key in S) print S[key], key}'|sort -rn -k1|head -5 >/tmp/tmp.log
}
ipt(){
local ip=$1
if [ `iptables -L -n|grep "$ip"|wc -l` -lt 1 ];then
iptables -I INPUT -s $ip -j DROP
echo "$line is dropped" >>/tmp/droplist_$(date +%F).log
fi
}
main(){
JudgeExt $file
while true
do
IpCount $file
while read line
do
ip=`echo $line|awk '{print $2}'`
count=`echo $line|awk '{print $1}'`
if [ $count -gt 3 ];then
ipt $ip
fi
done</tmp/tmp.log
done
}
main

Shell编程之while循环和until循环的更多相关文章

  1. shell编程之awk命令详解

    shell编程之awk命令详解 a:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; out ...

  2. 03 shell编程之case语句与函数

    本文所有内容均来自当年博主当年学习笔记,若有不足欢迎指正 Shell编程之case语句与函数 学习目标: 掌握case语句编程 掌握shell函数的使用 目录结构: Case语句 Case语句的作用 ...

  3. shell编程之case分支语句

    shell编程之case分支语句 case分支语句和if的多分支语句很相似. if多分支语句一般用在有(区间范围)的地方 :例如:0-100之间. if需要判断多个不同的条件. case的分支语句用在 ...

  4. shell编程之if语句

    shell编程之if判断 目录 shell编程之if判断 1.整数比较 2.字符串比较 3.举例 1.数字比较 2.字符串比较 4.Other 1.整数比较 -eq 等于,如:if [ "$ ...

  5. shell 编程之 for while until 循环

    shell 的for循环 的格式如下: for 变量  in 列表 do ... done 列表是一组值的序列 每个值通过空格隔开 每循环一次,列表中的下一个值赋给变量 in 列表是可选的,如果不用他 ...

  6. Shell编程之for和select循环

    一.for和select循环 1.for循环语法 for 变量名 in 变量取值列表 do 指令... done C语言型for循环 for ((exp1; exp2; exp3)) do 指令... ...

  7. shell编程之BASH变量(2)

    变量命名规范 在bash中,变量的默认类型都是字符串型,定义 name = 'kk' 变量分类 用户自定义变量.变量自定义的 环境变量:这种变量中主要保存的是和系统操作环境相关的数据.变量可以自定义, ...

  8. shell编程之99乘法表

    #99乘法表#!/bin/bash #第一种写法 ` #`seq ` 使用反撇号括起来的(不是单引号),表示命令替换 do for j in `seq $i` #seq可以使用变量 do echo - ...

  9. Shell编程之Shift的用法

    位置参数可以用shift命令左移.比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1.$2.$3丢弃,$0不移动.不带参数的shift命令相当于shift 1. 非常 ...

随机推荐

  1. select option 不可以选

    <select> <option>Volvo</option> <option>Saab</option> <option disab ...

  2. Vmware私有云虚拟机(CentOS 6.5 OS)之根分区扩容

    注:适用于未使用lvm管理的分区,目前仅在CentOS 6.5 上操作,其他系统尚未测试,请谨慎操作 一.查看当前分区状况 [root@disk-test ~]# df -h Filesystem   ...

  3. sqoop1.99.3配置过程

    感谢:http://www.myexception.cn/database/1600202.html 官网配置指导:http://sqoop.apache.org/docs/1.99.3/Instal ...

  4. Entity Framework中的主从表关系的使用

    其关系图: 我们使用Entity Framework生成映射关系如下: 其中author表中的books导航属性为一个集合,表示当前作者的书. 在页面中我们可以使用如下代码来实现: 代码中author ...

  5. 绝对定位position: absolute;

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Linux下汇编语言------计算n的阶乘

    用高级语言比方C语言写个阶乘非常easy,那如今就来熟悉下Linux使用AT&T汇编格式写一个程序来计算阶乘吧 写法一是 使用跳转指令实现.写法二是使用函数来实现 约定:本程序没有将结果打印在 ...

  7. 7、easyui 表单

    这是最后一个小节了,后面将会使用一个小项目来进一步实用讲解: 在之前的什么相关只是点都以及讲过了或者说涉及到过,如datagrid表格,树形菜单,布局面板panel,页签,拖放功能,只是在表格的属性细 ...

  8. 深入理解line

    什么是行间距? 古时候我们使用印刷机来出来文字.印刷出来的每个字,都位于独立的一个块中. 行间距,即传说中控制两行文字垂直距离的东东.在CSS中,line-height被用来控制行与行之间垂直距离. ...

  9. hdu1829(A Bug's Life)

    题目链接:传送门 题目大意:有n个昆虫,有m组关系,接下来m行表示两个昆虫性别不同,问是否有矛盾情况(同男同女) 题目思路:并查集的高级应用,开两倍数组大小,后n个数组表示和当前昆虫不同性别的集合 # ...

  10. 《从零开始学Swift》学习笔记(Day 18)——有几个分支语句?

    原创文章,欢迎转载.转载请注明:关东升的博客       分支语句又称条件语句,Swift编程语言提供了if.switch和guard三种分支语句. if语句 由if语句引导的选择结构有if结构.if ...