概述看多了shell脚本实例自然会产生写shell脚本的想法,所以我一般推荐看脚本实例来练习shell脚本。下面是几个shell脚本的例子。1、监控Nginx访问日志502,并采取相应措施。假设服务器环境为lnmp,最近访问经常出现502现象,重启php-fpm服务后502错误消失。因此,有必要编写一个监控脚本。一旦出现502,会自动重启php-fpm服务。#场景:#1。访问日志文件的路径:/data/log/access.log#2。脚本无限循环,每10秒检测一次,10秒日志数为300条,出现502条的比例不低于10%(30条)需要重启php-fpm服务#3。重启命令为:/etc/init.d/php-fpmrestart#!/bin/bash################################################################监控Nginx访问日志502情况,并采取相应措施###########################################################log=/data/log/access.logN=30#设置阈值while:do#查看accesslog的最新300条,统计502个err=`tail-n300$log|grep-c'502"'`if[$err-ge$N]then/etc/init.d/php-fpmrestart2>/dev/null#设置60s延迟防止脚本bug导致无限重启php-fpm服务sleep60fisleep10done2.删除一个文件前五行包含字母的行,同时删除第6行到第10行包含的所有字母1)准备一个测试文件,文件名为2.txt,第一行1234567没有包含字母line256789BBBBBBline367890CCCCCCCCline478asdfDDDDDDDDDDline5123456EEEEEEEEline61234567ASDFline756789ASDFline867890ASDFline978asdfADSFline10123456AAAAline1167890ASDFline123ADF231DS4脚本)如下:#!/bin/bash#################################################################删除文档前五行包含字母的行,并删除所有字母包含在第6到10行中################################################################sed-n'1,5'p2.txt|sed'/[a-zA-Z]/'dsed-n'6,10'p2.txt|seds'/[a-zA-Z]//'gsed-n'11,$'p2.txt#最后的结果只是把结果打印在屏幕上,如果要直接改文件,可以将输出结果写入临时文件中,替换2.txt或者使用-i选项3,使用shell打印示例语句中小于6个字母的单词#示例语句:#Bashalsointerpretsanumberofmulti-characteroptions。#!/bin/bash#################################################################shell打印例句中少于6个字母的词##############################################################forsinBash还解释了多个多字符选项.don=`echo$s|wc-c`if[$n-lt6]thenecho$sfidone4。输入数字并运行相应的命令####################################################################输入数字运行相应的命令###################################################################回声"*cmdmenu*1-date2-ls3-who4-pwd0-exit"while:do#Captureuserinputvalueread-p"pleaseinputnumber:"nn1=`echo$n|seds'/[0-9]//'g`#空输入检测if[-z"$n"]thencontinuefi#非数字输入检测if[-n"$n1"]thenexit0fibreakdonecase$nin1)date;;2)ls;;3)who;;4)pwd;;0)break;;#提示输入1-4以外的数字*)echo"pleaseinputnumberis[1-4]"esac5.创建10个用户,分别设置密码。密码需要10个字符,包括大小写字母和数字。最后,你需要把每个每个用户的密码存放在指定的文件#!/bin/bash#################################################################创建10个用户,分别设置密码。密码需要10个字符,包含大小写字母和数字每个用户的密码需要存放在指定的文件中#前提:安装mkpasswd命令##################################################################产生asequenceof10users(00-09)foruin`seq-w009`do#Createuseruseradduser_$u#Generatepasswordp=`mkpasswd-s0-l10`#Readpasswordfromstandardinputtomodify(不安全)echo$p|passwd--stdinuser_$u#定时修改密码echo-e"$p\n$p"|passwduser_$u#将创建的用户和对应的密码记录到日志文件中echo"user_$u$p">>/tmp/用户密码完成6.监控httpd进程数,根据监控情况做出相应的处理Process#!/bin/bash####################################################################################################################################要求:#1。每10s监控一次httpd进程数,如果进程数大于等于500,则自动重启Apache服务,并检查服务重启是否成功。#2。如果失败,则需要重新开始。如果重启5次后仍然失败,将向管理员发送告警邮件,并退出测试。#3.如果启动成功,请等待1分钟,然后再次查看httpd进程数。如果进程数正常,则恢复正常检测(每10s检测一次),否则放弃重启并向管理员发送警告邮件,并退出检测###################################################################################################################################计数器函数check_service(){j=0foriin`seq15`do#重启Apache的命令/usr/local/apache2/bin/apachectlrestart2>/var/log/httpderr.log#判断服务是否重启成功if[$?-eq0]thenbreakelsej=$[$j+1]fi#判断服务是否尝试重启5次if[$j-eq5]thenmail.pyexitfidone}while:don=`pgrep-lhttpd|wc-l`#判断httpd服务进程数是否超过500if[$n-gt500]then/usr/local/apache2/bin/apachectlrestartif[$?-ne0]thencheck_serviceelsesleep60n2=`pgrep-lhttpd|wc-l`#判断重启后是否还超过500if[$n2-gt500]thenmail.pyexitfififi#every每10s7检测一次sleep10done。根据web访问日志,屏蔽请求量异常的IP。如果半小时后IP恢复正常,则解封#!/bin/bash######################################################################################根据web访问日志,对请求量异常的IP进行封禁,如果半小时后IP恢复正常,则解除封禁##########################################################################################logfile=/data/log/access.log#显示一分钟前的小时和分钟d1=`date-d"-1minute"+%H%M`d2=`date+%M`ipt=/sbin/iptablesips=/tmp/ips.txtblock(){#过滤一分钟前的所有日志并提取IP并统计数量ofvisitsgrep'$d1:'$logfile|awk'{print$1}'|sort-n|uniq-c|sort-n>$ips#使用for循环遍历100次以上的IP并拦截foriin`awk'$1>100{print$2}'$ips`do$ipt-IINPUT-ptcp--dport80-s$i-jREJECTecho"`date+%F-%T`$i">>/tmp/badip.logdone}unblock(){#会被阻塞的生成的pkts个数小于10个IP依次遍历解锁forain`$ipt-nvLINPUT--line-numbers|grep'0.0.0.0/0'|awk'$2<10{print$1}'|sort-nr`do$ipt-DINPUT$adone$ipt-Z}#00分钟和30分钟时执行解封功能if[$d2-eq"00"]||[$d2-eq"30"]then#FirstUnblock并重新出块,因为刚刚出块时产生的pkts数量很少unblockblockelseblockfi
