循环
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rR8V4nih-1678373404130)(http://book.luffycity.com/linux-book/%E8%B6%85%E5%93%A5%E5%B8%A6%E4%BD%A0%E5%AD%A6Shell/pic/image-20210317211220720.png)]
循环非常重要,且常见
- 你每天循环的路线去上班
- 你每天都要吃一个煎饼果子
- 你每天都要洗头
- 。。。
遇见特殊情况,循环中断
- 公司今天放假
- 煎饼果子没出摊
- 你今天偷懒不想洗头
- 。。
while循环
循环语句在shell中有
- While
- until
- for
- select
while常用于守护进程,持续运行的程序
语法
while <条件表达式>
do
代码。。。
done
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tq6i1PNA-1678373404132)(http://book.luffycity.com/linux-book/%E8%B6%85%E5%93%A5%E5%B8%A6%E4%BD%A0%E5%AD%A6Shell/pic/image-20210317212323735.png)]
until循环
until循环和while循环类似,但是until是直到
的含义
- 在条件不成立时,执行循环体
- 条件成立后,循环结束
Josen的总结
while,成立继续执行do done
until,不成立继续执行do done
shell循环实践
每两秒输出一次系统负载
[root@chaogelinux shell_program]# cat while_1.sh
#!/bin/bash
while [ 1 -lt 2 ]
do
uptime
sleep 2
done
# 执行
[root@chaogelinux shell_program]# bash while_1.sh
21:30:14 up 16 days, 7:51, 1 user, load average: 0.00, 0.01, 0.05
21:30:16 up 16 days, 7:51, 1 user, load average: 0.00, 0.01, 0.05
^C
负载信息写入文件,且在后台运行
[root@chaogelinux shell_program]# cat while_1.sh
#!/bin/bash
while true
do
uptime >> /tmp/uptime.log
sleep 2
done
后台运行脚本
[root@chaogelinux shell_program]# bash while_1.sh &
[1] 21535
# 查看任务
[root@chaogelinux shell_program]# jobs
[1]+ 运行中 bash while_1.sh &
# 查看日志
[root@chaogelinux shell_program]# tail -f /tmp/uptime.log
21:32:29 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:31 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:33 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:35 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:37 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:39 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:41 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:43 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:45 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:47 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:49 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
21:32:51 up 16 days, 7:53, 1 user, load average: 0.00, 0.01, 0.05
后台运行命令的方法
- command &
- nohup command &
- screen命令保持会话
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lvcUzazB-1678373404134)(http://book.luffycity.com/linux-book/%E8%B6%85%E5%93%A5%E5%B8%A6%E4%BD%A0%E5%AD%A6Shell/pic/image-20210317213441723.png)]
进程管理命令
- Kill,killall,pkill
- ps,pstree
- top
- nohup,用户退出系统后继续后台工作
- pgrep,进行匹配过滤
- strace,进程追踪
- ltrace,进程调用函数追踪
实践循环
打印数字54321
单中括号
[root@chaogelinux shell_program]# cat while_2.sh
#!/bin/bash
i=5
while [ $i -gt 0 ] # 条件判断,变量大于0时成立
do
echo "$i"
((i--)) # i变量的自减一
done
双小括号
[root@chaogelinux shell_program]# cat while_2.sh
#!/bin/bash
i=5
while (( i > 0 )) # 双小括号条件判断,变量大于0时成立
do
echo "$i"
((i--)) # i变量的自减一
done
双中括号
[root@chaogelinux shell_program]# cat while_2.sh
#!/bin/bash
i=5
while [[ $i > 0 ]] # 条件判断,变量大于0时成立
do
echo "$i"
((i--)) # i变量的自减一
done
脚本传递数字
[root@chaogelinux shell_program]# cat while_2.sh
#!/bin/bash
i="$1"
while [ $i -gt 0 ]
do
echo $i
((i--))
done
[root@chaogelinux shell_program]# bash while_2.sh 10
10
9
8
7
6
5
4
3
2
1
使用until命令
可以看出就是和while相反的条件
[root@chaogelinux shell_program]# cat until_1.sh
#!/bin/bash
i=5
until [ $i -lt 1 ]
do
echo $i
((i--))
done
[root@chaogelinux shell_program]# bash until_1.sh
5
4
3
2
1
实践循环二
求1~100的和
提示:双括号用于变量计算
[root@chaogelinux shell_program]# cat while_3.sh
#!/bin/bash
i=1
sum=0
while [ $i -le 100 ]
do
((sum=sum+i)) # 把i当前值和sum相加,且重新赋值
((i++))# 每次加一,也就是1,2,3,4.。。
done
[ "$sum" -ne 0 ] && printf "1~100总和:$sum\n"
[root@chaogelinux shell_program]#
# 执行
[root@chaogelinux shell_program]# bash while_3.sh
1~100总和:5050
While生产实践
while监控网站,每隔10s确定一次
#!/bin/bash
if [ $# -ne 1 ]
then
echo "Usage: $0 url"
exit 1
fi
while true
do
# 如果结果非1行,表示网站由问题
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 website error."
else
echo "$1 is ok!"
fi
sleep 10
done
执行
[root@chaogelinux shell_program]# bash while_check_url.sh www.pythonav.cn
www.pythonav.cn is ok!
www.pythonav.cn is ok!
检测多个网站是否正常
#!bin/bash
# 定义shell数组
url_list=(
http://www.pythonav.cn
http://www.baidu.com
http://www.taobao.com
)
# 定义一个倒计时的函数
wait(){
echo "3秒后,对url进行检查"
echo
# for循环
for i in $(seq 3 -1 1)
do
echo "$i"
sleep 1
done
echo "--程序开始开始--"
}
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
echo "${url_list[$i]} is working!!!"
else
echo "${url_list[$i]} is error!!!"
fi
done
((check_count++))
}
main(){
while true
do
check_url
echo "-------检查次数是:${check_count}-----------"
sleep 3
done
}
main
while读取web日志
需求:分析ngixn的日志,把每一行的访问记录,
计算body_bytes_sent,nginx返回给客户端的响应体的字节数
计算综合
文件资源如下
[root@chaogelinux logs]# ls -lh access.log
-rw-r--r-- 1 root root 42M 3月 19 21:23 access.log
开发while脚本
shell读取文件的方式
exec命令读取文件
exec 执行完命令后,退出所在用户权限
# exec读入文件
exec <FILE
exec读取文件
exec <FILE
sum=0
while read line
do
cmd
done
cat读取文件
cat FILE|while read line
do
cmd
done
while结合done读取数据
在while循环结尾done处,通过输入重定向,读取指定文件
while read line
do
cmd
done<FILE
模拟cat命令
[root@chaogelinux scripts]# cat cat_while.sh
#!/bin/bash
while read line
do
echo $line
done<$1
执行
[root@chaogelinux scripts]# bash cat_while.sh /etc/hosts
127.0.0.1 VM_32_137_centos VM_32_137_centos
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4
::1 VM_32_137_centos VM_32_137_centos
::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
分析nginx日志
利用exec读取文件内容
[root@chaogelinux scripts]# cat while_access.sh
#!/bin/bash
sum=0
exec <$1
while read line
do
size=`echo $line|awk '{print $10}'` # awk截取数据大小
expr $size + 1 &>/dev/null # 判断是否是数字
if [ $? -ne 0 ];then
continue
fi
((sum=sum+$size)) # 循环的值,累加且赋值
done
echo "${1}:total: ${sum}bytes=`echo $((${sum}/1024))`KB"
执行
[root@chaogelinux scripts]# bash while_access.sh /opt/ngx112/logs/500-access.log
/opt/ngx112/logs/500-access.log:total:2200902bytes=2149KB
防DDOS攻击脚本
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Py5ovNX-1678373404136)(http://book.luffycity.com/linux-book/%E8%B6%85%E5%93%A5%E5%B8%A6%E4%BD%A0%E5%AD%A6Shell/pic/image-20210319222406588.png)]
分布式拒绝服务(DDoS)攻击是通过大规模互联网流量淹没目标服务器或其周边基础设施,以破坏目标服务器、服务或网络正常流量的恶意行为。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vGuJpvut-1678373404136)(http://book.luffycity.com/linux-book/%E8%B6%85%E5%93%A5%E5%B8%A6%E4%BD%A0%E5%AD%A6Shell/pic/image-20210319222934712.png)]
作为运维,也需要从一些基础手段,减少服务器被恶意访问,减轻服务器的压力
思路:
根据web日志统计网络链接数,监控某个IP的并发连接数,若是短时间内PV达到100,可以证明非正常人发出的请求,如网络爬虫,可以将其流量封禁。
iptables -I INPUT -s ip -j DROP
shell防ddos攻击脚本
#!/bin/bash
file=$1
while true
do
#过滤出日志的客户端ip地址
awk "{print $1}" $1|grep -v "^$"|sort|uniq -c >/tmp/access_ip.log
# 对ip地址文件分析
exec </tmp/access_ip.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 ]
# 如果pv大于500,并且iptables没有封禁该ip
then
iptables -I INPUT -s $ip -j DROP
echo "$line is dropped" >>/tmp/droplist_$(date +%F).log
fi
done
sleep 3600
done
总结
- while循环一般用于希望循环运行,持续运行,不退出的应用,例如守护进程在后台运行
- case语句可以用if语句代替,而当如启停脚本开发时,对固定规则的字符串判断,可以用case