目录
- SHELL脚本
- 一、shell概述
- 1、基本信息
- 2、规范的shell脚本
- 3、脚本的运行方式
- 1、自定义变量
- 2、环境变量
- 3、位置变量
- 4、预定义变量
- 5、查看变量
- 6、扩展知识
- 7、变量的发布
- 1、expr
- 2、$[] 或 $(())
- 3、let
- 4、bc
- 1、字符串
- 2、数字
- 3、文件
- 4、逻辑测试
- 1、if 判断
- 2、case 分支
- 1、for循环
- 2、while循环
- 3、循环的控制
- 1、截取
- 2、替换
- 3、删除(掐头去尾)
- 4、初值
- 1、基本正则
- 2、扩展正则
- 3、grep
- 1、格式
- 2、基本应用
- 3、实际使用
- 1、格式
- 2、条件的使用
- 2.1、正则
- 2.2、字符、数值比较
- 2.3、逻辑符号:&&、||
- 2.4、计算
- 3.1、if
- 3.2、BEGIN、END
- 1、监控脚本
- 2、安全检测脚本
- 3、sed、awk对同一案例的不同应用
- 3、监控 web 服务
- 4、监控 db 服务
- 5、监控 web 站点目录
- 6、监控 MySQL 主从同步
- 7、解决DOS攻击
SHELL脚本
一、shell概述
1、基本信息
概念:利用Linux命令写成的代码,通过解释器进行运行的程序。
- /bin/bash:默认解释器
- cat /etc/shells:查看所有解释器
- yum -y install ksh:安装新解释器
- bash的优点:tab键,快捷键,历史记录,管道符,重定向。
2、规范的shell脚本
- 声明解释器:#!/bin/bash
- 注释脚本功能,变量含义等
- 可执行的代码。
3、脚本的运行方式
- 添加x执行权限
- 使用解释器执行,开启子进程:bash xxx.sh
- 使用当前解释器执行,不开启子进程:source xxx.sh
/dev/null # 黑洞设备,专用于收集不要的输出信息exit 1 # 在shell脚本中,放在一个命令执行后,将此命令定义为错误输出,即$?为非0
二、变量
1、自定义变量
变量名称=值
- 名称:大小写字母、数字、下划线不能用特殊字符,不能以数字开头
2、环境变量
- 系统默认存在的变量
- USER、UID、HOME、HOSTNAME、 SHELL、PATH、PS1、PS2
3、位置变量
#!/bin/bashecho $1 #脚本后第1个参数echo $2 #脚本后第2个参数echo $3 #脚本后第3个参数... ...echo $10 #脚本后第10个参数
4、预定义变量
#!/bin/bashecho $0 #脚本名echo $$ #脚本执行时的进程ID号echo $* #所有参数echo $? #上一条命令是否执行成功echo $# #参数的个数
5、查看变量
[root@server ~]# env #查看所有环境变量[root@server ~]# set #查看所有变量
6、扩展知识
-
\” \” :双引号,界定范围
-
’ ’ :单引号,界定范围。屏蔽特殊符号
-
“ :反撇号,获取命令执行的结果
-
$():跟反撇号等同,获取命令执行的结果
-
交互式脚本:read -p “提示信息,自定义” 变量
-
stty -echo:屏蔽回显
-
stty echo :恢复回显
7、变量的发布
[root@ser ~]# export #发布全局变量[root@ser ~]# export a=10 #发布新的全局变量[root@ser ~]# export b #将局部变量扩展为全局变量[root@ser ~]# export -n a #取消全局变量[root@ser ~]# unset a #取消变量定义(删除变量)
三、运算
1、expr
#注:数字与运算符号之间要有空格expr 1 + 1 加expr 1 - 1 减expr 2 \\* 2 乘expr 10 / 5 除expr 10 % 3 求模,取余数
2、$[] 或 $(())
#无需空格ehco $[1+1] 加echo $[1-1] 减echo [2*2] 乘echo [10/2] 除echo [10%5] 取余数
3、let
let 用于变量计算。结果不显示let a=1+1let b=c+d变量的自增减:let a=a-1 相当于 let a--let a=a+1 相当于 let a++let a=a+2 let a+=2let a=a-2 let a-=2let a=a*2 let a*=2let a=a/2 let a/=2let a=a%2 let a%=2
4、bc
bc 常用于小数的计算echo \"1.2+3.5\" | bcecho \"scale=3;10/3\" | bc #scale定义小数点后显示几位。
四、条件测试
1、字符串
- ==是否相等
- != 是否不等
- -z 是否为空
2、数字
- -eq:等于;-ne:不等于
- -lt:小于;-le:小于等于
- -gt:大于;-ge:大于等于
3、文件
- -e:存在为真,不管是文件还是目录
- -f:存在,且是文件才为真
- -d:存在,且是目录才为真
- -r:是否有读权限
- -w:是否有写权限
- -x:是否有执行权限
4、逻辑测试
- &&(并且):之前的任务成功,则执行后面的任务
- || (或者):之前的任务失败,才执行后面的任务
五、判断结构
1、if 判断
# 基本格式#单分支if [条件测试];then命令fi# 双分支if [条件测试];then命令else命令fi# 多分支if [条件测试];then命令elif [条件测试];then命令elif [条件测试];then命令... ...else命令fi
2、case 分支
- case分支,相当于简化版本的if,功能 不如if强大,但是代码比较精简。一般用于制作一些小工具。
# 格式:case 变量 in模式1)命令序列1;;模式2)命令序列2;;*)默认命令序列 # 最后一个可以不用分号。esac-----------------------------------------------------------------------#!/bin/bashcase $1 inredhat)echo \"fedora\";;fedora)echo \"redhat\";;*) //默认输出脚本用法echo \"用法: $0 {redhat|fedora}\"esac
六、循环结构
1、for循环
- 有限的循环,循环的次数和值有关
#基本结构:for 变量名 in 循环值1、2、3....do命令done----------------------------例1:#!/bin/bashfor i in {1..10}doecho $idone----------------------------例2:#!/bin/basha=10for i in `seq $a` #这里有变量时不能用大括号{}doecho $idone
2、while循环
- 无限循环(死循环)
#基本结构:while 条件测试do命令done-------------------------------------------#!/bin/bashx=$[RANDOM%100] #RANDOM:生成随机数。y=0while : #这里\':\'是指任何条件都成立dolet y++read -p \"猜数(0-99):\" nif [ $n -gt $x ];thenecho \"大了\"elif [ $n -lt $x ];thenecho \"小了\"elseecho \"对了\"echo \"共猜了$y次\"fidone
3、循环的控制
- exit:退出脚本
- break:终止循环,执行循环之后的任务
- continue:终止当前循环,继续下一次循环
七、函数
- 函数一般用在脚本里面,对于一些经常性用到的命令进行一个定义,然后在脚本中可以直接调用。
# 格式1:function 函数名 {命令序列1命令序列2... ...}# 格式2:函数名 () {命令序列... ...}
例:
# 使用函数编写方便调用不同颜色字体的脚本:#!/bin/bashcecho (){echo -e \"\\033[$1m$2\\033[0m\" # 定义了一个函数命令}cecho 31 ABCDEFG # 调用函数命令cecho 32 ABCDEFGcecho 33 ABCDEFGcecho 34 ABCDEFGcecho 35 ABCDEFGcecho 36 ABCDEFGcecho 37 ABCDEFG# 炸弹脚本#!/bin/bashabc(){abc|abc &}abc
八、字符串的处理
1、截取
# 格式:${变量名:起始位置:长度} # 起始位置的计算从0开始# 例:b=65498165echo ${b:3:4} # 截取变量b,从第4位开始截取4位echo ${b::4} # 起始为0时可省略0# 应用:编写随机获取6位密码的脚本#!/bin/bashx=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789for i in {1..6}don=${RANDOM%62}p=${x:n:1}pass=$p$passdoneecho $pass
2、替换
# 格式:${变量名/旧/新}# 例:b=1802874632echo ${b/1/a} # 将 1 替换为 aecho ${b/8/a} # 将 8 替换为 aecho ${b//8/a} # 将所有 8 替换为 aecho ${b/0/} # 将数字 0 替换为空,相当于删除
3、删除(掐头去尾)
# 格式:${变量名#*关键词} # 从左往右删除 掐头# 例a=\"root:x:0:0:root:/root:/bin/bash\"echo ${a#root} # 删除到第一个 rootecho ${a##*root} # 删除到最后一个 root,以及此 root 左边所有echo ${a##*/} # 删除到最后一个/,以及此/左边所有echo ${a#*:root} # 删除:root,以及左边所有--------------------------------------------# 格式${变量名%关键词*} # 从右往左删除 去尾# 例echo ${a%bash} # 从右往左删除到 bashecho ${a%root*} # 从右往左删除到第一个 root,以及 root 右边所有echo ${a%/*} # 从右往左删除到第一个/,以及/右边所有echo ${a%%/*} # 从右往左删除到最后一个/,以及/右边所有--------------------------------------------------------------------# 利用字符串删除功能,编写批量修改文件扩展名的脚本:#!/bin/bashfor i in `ls *.txt` 首先找到修改目标don=${i%.*} 利用删除中的去尾将扩展名删除,剩下不带扩展名的文件名mv $i $n.doc 在将上述文件名与.doc 组合,修改为新名字done
4、初值
# 格式${变量名:-}# 例[root@server0 opt]# a=[root@server0 opt]# echo ${a:-123} //当变量是空时调用初值123[root@server0 opt]# a=789[root@server0 opt]# echo ${a:-123} //变量有值时不使用初值789------------------------------------------------------------------------# 配置密码时使用初值#!/bin/bashread -p \"请输入用户名:\" uuseradd $uread -p \"请输入密码:\" pecho ${p:-123456} | passwd --stdin $u # 当输入密码为空时,默认密码为123456。
九、正则
1、基本正则
正则符号 | 描述 |
---|---|
^ | 匹配行首 |
$ | 匹配行尾 |
[ ] | 集合,匹配集合中的任意单个字符 |
[^] | 对集合取反 |
. | 匹配任意单个字符 |
* | 匹配前一个字符任意次数。不允许单独使用 |
\\ {n,m\\ } | 匹配前一个字符:n 到 m 次 |
\\ {n\\ } | 匹配前一个字符:n 次 |
\\ {n,\\ } | 匹配前一个字符:n 次 及以上 |
\\(\\ ) | 保留 |
2、扩展正则
正则符号 | 描述 |
---|---|
+ | 最少匹配一次 |
? | 最多匹配一次 |
{n,m} | 匹配 n 到 m 次 |
( ) | 保留,使组合成整体 |
| | 或者 |
\\b | 单词边界 |
3、grep
- 配合基本正则
- 格式为:grep “正则” 文件
# 基本正则的使用:cat /etc/passwd > user # 素材grep ^root user # 搜索以root开头的grep in$ user # 搜索以in结尾的grep [in] user # 搜索字母 i 或者 ngrep [^in] user # 搜索除了字母 i 或者 n 以外所有的grep \".\" user 搜索任意单个字符。包括空格,但不包括空行。grep \".*\" user 搜索任意。包括空行。grep \"ro*t\" user # 搜索r?t,r与t之间任意个ogrep \"0:\\{2\\}\" user # 搜索 0::grep \"\\(0:\\)\\{2\\}\" user # 搜索 0:0:
- 扩展正则
- grep -E 或 egrep
grep -E \"ro+t\" useregrep \"ro+t\" usergrep -E \"bi?n\" useregrep \"bi?n\" usergrep -E \"ro{2,4}t\" user # 搜索ro?t,其中o出现2到4次grep -E \"ro|in\" user # 搜索ro或ingrep -E \"\\bthe\" user # 搜索单词the,前面不能有数字字母下划线grep -E \"0:{2}\" user # 搜索0::grep -E \"(0:){2}\" user # 搜索 0:0:
十、Sed
1、格式
流式编辑器。非交互式修改文本,支持正则。
- 工作方式:逐行处理。
# 使用方式:sed 选项 \'(定址符)/正则/指令\' 被处理文件前置命令 | sed 选项 \'(定址符)/正则/指令\'sed 选项 \'(定址符)/正则/指令1;(定址符)/正则/指令2;\' 文件 # 用分号;隔开多条指令。# 选项:-n:屏蔽默认输出-r:支持扩展正则-i:写入文件# 指令:p:输出d:删除s:替换a:在行下追加i:在行上追加c:整行替换# 定址符,定址符可以不写,不写时,默认逐行处理。\'p\' # 逐行处理。即输出全部\'1p\' # 输出:第1行\'2,5p\' # 输出:第2~5行\'3p;7p\' # 输出:第3行,第7行\'4,+2p\' # 输出:第4行,及后面的2行\'1~2p\' # 输出:奇数行\'2~2p\' # 输出:偶数行\'=\' # 显示全部行号\'$=\' # 显示最后一行行号
2、基本应用
# 替换sed \'s/xml/abc/\' a.txt # 将每行中的第1个xml替换成abcsed \'s/xml/abc/3\' a.txt # 将每行中的第3个xml替换成abcsed \'s/xml/abc/g\' a.txt # 将全部xml替换成abcsed \'s/xml//g\' a.txt # 将全部xml替换成空,即删除sed \'s/\\/bin\\/bash/\\/sbin\\/sh/\' user # 将/bin/bash 替换成 /sbin/shsed \'s#/bin/bash#/sbin/sh\' usersed \'s!/bin/bash!/sbin/sh\' usersed \'s(/bin/bash(/sbin/sh\' user# 效果与上一条一致。当替换字符中有与替换符冲突时,可以使用数字键上方的任意一种特殊符号代替------------------------------------------------------------------------# 正则中保留的特殊使用:()保留,也相当于复制,使用\\1\\2\\3 进行粘贴sed -r \'s/^(.)(.*)(.)$/\\3\\2\\1/\' a.tat # 将每行的第一个字符与最后一个字符对调表示全部数字[0-9],全部大写字母[A-Z],全部大小写字母[a-Z]-------------------------------------------------------------------------# 行下、行上追加,整行替换(在与替换内容之间空格一下)sed \'a xxxxxx\' a.txt # 所有行下添加sed \'1a xxxxxx\' a.txt # 第1行行下添加sed \'1,2a xxxx\' a.txt # 1~2行下添加sed \'i xxxxxx\' a.txt # 所有行上添加sed \'2i xxxxx\' a.txt # 第2行上添加sed \'c xxxxx\' a.txt # 所有行替换sed \'/abc/c xxxx\' a.txt # 包含abc的行替换成xxxx
3、实际使用
- 编写脚本,找出使用 bash 的用户,按照 名字 –> 密码 的格式输出
#!/bin/bashu=`sed -n \'/bash$/s/:.*//p\' /etc/passwd` # 找到bash用户,并把名字存入变量bfor i in $udox=`grep $i:/etc/shadow`a1=${x#*:} # 掐头a2=${a1%%:*} # 去尾echo \"$i ---> $a2\"done
十一、awk
1、格式
- awk 数据过滤软件:可以进行精确搜索
- awk 的默认工作模式:逐行处理。
# 格式:awk 选项 \'条件{指令}\' 被处理文件 # 条件和指令需要使用单引号,指令必须用{}前置命令 | awk 选项 \'条件{指令}\'awk 选项 \'条件{指令1;指令2;指令3}\' 文件 # 多条指令间用分号;隔开# 常用选项-F # 自定义分隔符。默认情况下,分隔符是空格或tab-F: # 以:为分隔符-F[:/] # 以:和/ 为分隔符# 常用指令print 输出# 内置变量$0 所有列$1 第1列$2 第2列... ...NF 列NR 行
2、条件的使用
2.1、正则
awk \'/正则条件/指令\' # 在使用正则时:要用斜线# ~ 包含; !~ 不包含; 当内置变量与正则使用时需要用到awk \'$1~/正则/指令‘ # 第1列包含...awk \'$1!~/正则/指令\' # 第1列不包含...
2.2、字符、数值比较
==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于)# 不写指令时,默认指令为输出{print}# 常量必须用双引号\"\"标注。awk \'NR==2\' a.txt # 输出行数等于2的内容。awk \'$1==\"root\"{print}\' a.txt #awk \'$1!=\"root\"\' a.txtawk \'$3<5\' a.txt # 输出第3列小于5的行awk \'$3==\"5\"\' a.txt # 输出第3列的字符等于0的行。
2.3、逻辑符号:&&、||
# 逻辑符号一般配合其它的条件因素进行使用。awk \'$2<10 && $2>5\' a.txtawk \'$2<10 || $4>15\' a.txt
2.4、计算
seq 100 | awk \'$1%7==0 || $1~/7/\' # 列出100以内整数中7的位数,或包含7的数。awk \'BEGIN{x++;print x}\'awk \'BEGIN{x=8; print x+=2}\'awk \'BEGIN{print 2+3}\'awk \'BEGIN{print 2*3}\'awk \'BEGIN{print 23%8}\'
3、工作流程的控制
3.1、if
# if中的条件仍然可以使用正则。if(条件){命令}if(条件){命令} else{命令}if(条件){} else if(条件){}.....# awk中if是个指令,必须放在{}中,但是可以用空格隔开,awk不关心空格。awk 选项 \'(条件){ if(){} else{} }\' 文件
3.2、BEGIN、END
# BEGIN{}任务:只执行一次;{}常规任务:逐行执行;END{}:只执行一次awk 选项 \'(条件) BEGIN{} {} END{}\' 文件# 在awk中,是无视空格的。如果输出需要一定的排版,可以用\\t\\t :制表符。相当于tab键。在输出的时候可以起到一定的排版效果。awk -F: \'BEGIN{print \"User \\t UID \\t Hone\"} {print $1 \"\\t\" $3 \"\\t\" $6} END{print \"总计 \"NR\" 行\"}\' /etc/passwd
4、数组
- 数组:一个可以存多个值的变量。本质上,仍是一个变量。
- 定义数组:数组名[下标]=元素值
- 调用数组:数组名[下标]
- 遍历数组:for(变量 in 数组名){print 数组名[变量]}
- awk数组的下标除了可以使用数字,也可以使用字符串,字符串需要使用双引号
[root@svr5 ~]# awk \'BEGIN{a[0]=0;a[1]=11;a[2]=22; for(i in a){print i,a[i]}}\'0 01 112 22[root@svr5 ~]# awk \'BEGIN{a[\"hehe\"]=11;print a[\"hehe\"]}\'11遍历数组:for(变量 in 数组名){print 数组名[变量]}详解:这里for循环中,是将数组的下标分别赋值给变量,再通过输出数组的格式,逐一输出数组值。
- 实际应用
# 统计Web访问量[root@svr5 ~]# awk \'{ip[$1]++} \\> END{for(i in ip) {print ip[i],i }}\' /var/log/httpd/access_log4 127.0.0.117 192.168.4.513 192.168.4.110.. ..# 对访问量排序排名:[root@svr5 ~]# awk \'{ip[$1]++} END{for(i in ip) {print i,ip[i]}}\' /var/log/httpd/access_log | sort -nr17 192.168.4.513 192.168.4.1104 127.0.0.1.. ..# 排序命令sort -r # 按数字升序排列sort -n # 反序sort -k # 指定按第几个字段排序
awk细节注意点
- 指令中如果输出常量,则需要使用双引号。否则,系统会识别为变量,输出会为空。
- 但是,在常量中,如果包含了变量,需要输出变量,则需要为变量也加上双引号,以抵消外面的双引效果。END{print “总计 “NR” 行”}
应用案例
1、监控脚本
查看性能数据的命令[root@svr5 ~]# uptime //查看CPU负载[root@svr5 ~]# ifconfig eth0 //查看网卡流量[root@svr5 ~]# free //查看内存信息[root@svr5 ~]# df //查看磁盘空间[root@svr5 ~]# wc -l /etc/passwd //查看计算机账户数量[root@svr5 ~]# who |wc -l //查看登录账户数量[root@svr5 ~]# rpm -qa |wc -l //查看已安装软件包数量
#!/bin/baship=`ifconfig eth0 | awk \'/inet /{print $2}\'`echo \"本地IP地址是:\"$ipcpu=`uptime | awk \'{print $NF}\'`#awk中NF为当前行的列数,$NF是最后一列echo \"本机CPU最近15分钟的负载是:\"$cpunet_in=`ifconfig eth0 | awk \'/RX p/{print $5}\'`echo \"入站网卡流量为:\"$net_innet_out=`ifconfig eth0 | awk \'/TX p/{print $5}\'`echo \"出站网卡流量为:\"$net_outmem=`free | awk \'/Mem/{print $4}\'`echo \"内存剩余容量为:\"$memdisk=`df | awk \'/\\/$/{print $4}\'`echo \"根分区剩余容量为:\"$diskuser=`cat /etc/passwd |wc -l`echo \"本地账户数量为:\"$userlogin=`who | wc -l`echo \"当前登陆计算机的账户数量为:\"$loginprocess=`ps aux | wc -l`echo \"当前计算机启动的进程数量为:\"$processsoft=`rpm -qa | wc -l`echo \"当前计算机已安装的软件数量为:\"$soft
2、安全检测脚本
- 检测ssh登录日志,如果远程登陆账号名错误3次,则屏蔽远程主机的IP
- 检测ssh登录日志,如果远程登陆密码错误3次,则屏蔽远程主机的IP
过滤帐户名失败的命令(登陆日志文件为/var/log/secure)[root@svr5 ~]# awk \'/Invalid user/{print $10}\' /var/log/secure过滤密码失败的命令[root@svr5 ~]# awk \'/Failed password/{print $11}\' /var/log/secure
#!/bin/bashawk \'/Failed password/{print $11}\' /var/log/secure | awk \'{ip[$1]++}END{for(i in ip){print ip[i],i}}\' | awk \'$1>3{print $2}\'awk \'/Invalid user/{print $10}\' /var/log/secure | awk \'{ip[$1]++}END{for(i in ip){print ip[i],i}}\' | awk \'$1>3{print $2}\'
3、sed、awk对同一案例的不同应用
要求:
- 分析出使用bash作登录Shell的本地用户
- 列出这些用户的shadow密码记录
- 按每行“用户名 – 密码记录”保存结果
#/bin/bashA=$(sed -n \'/bash$/s/:.*//p\' /etc/passwd) # 提取符合条件的账号记录for i in $A # 遍历账号记录dopass1=$(grep $i /etc/shadow)pass2=${pass1#*:}pass=${pass2%%:*}echo \"$i --> $pass\"done
#/bin/bashA=$(awk -F: \'/bash$/{print $1}\' /etc/passwd) # 提取符合条件的账号记录for i in $Adogrep $i /etc/shadow | awk -F: \'{print $1,\"-->\",$2}\'done
3、监控 web 服务
监控 web 服务是否正常,不低于 3 种监控策略。要求间隔 1 分钟,持续监控。
#!/bin/bash# . /etc/init.d/functions # 声明调用此文件中的函数。functions文件内有默认已经定义好的一些函数,如:echo_success、action \"\" /bin/true 等url=wwchengbi.cnPort=80check_web() {[ -f /etc/init.d/functions ]&& . /etc/init.d/functionsif [ \"`nc -z $url $Port && echo ok`\" = \"ok\" ];then#if [ \"`echo -e \'\\n\'| telnet $url $Port |grep Connected|wc -l`\" = \"1\" ];then#if [ \"`nmap $url -p $Port |grep open |wc -l`\" = \"1\" ];then#if [ \"`curl -I http://$url 2>/dev/null |head -1 |egrep \"200|302|301\" |wc -l`\" =\"1\" ];then#if [ \"`curl -I -s -o /dev/null -w \'%{http_code}\\n\' http://$url`\" = \"200\" ];thenaction \"$url $Port\" /bin/true # 打印指定内容,并提示是[OK]elseaction \"$url $Port /bin/false\" # 打印指定内容,并提示是[FAILED]fi}main() {while truedocheck_websleep 1mdone}main
4、监控 db 服务
- 监控 db 服务是否正常,不低于 3 种监控策略。要求间隔 1 分钟,持续监控。
#!bin/bashPort=3306user=pw=IP=check_db() {[ -f /etc/init.d/functions ] && . /etc/init.d/functionsif [ `lsof -i:$Port|wc -l` -gt 1 ];then#if [ \"`netstat -tunlp |grep 3306 |wc -l`\" = \"1\" ];then#if [ `mysql -u$user -p$pw -h$IP -P $Port -e \"show databases;\" |wc -l` -gt 1 ];thenaction \"MySQL $Port online\" /bin/trueelseaction \"MySQL $Port down\" /bin/falsefi}main() {while truedocheck_dbsleep 1sdone}main
5、监控 web 站点目录
- 监控 web 站点目录(/var/html/www)下所有文件是否被恶意篡改(文件内容被改了),如果有就打印改动的文件名(发邮件),定时任务每 3 分钟执行一次(10 分钟时间完成)。
#!/bin/bash# exec < filename:此命令会将stdin重定向到文件中. 从这句开始, 所有的stdin就都来自于这个文件了, 而不是标准输入(通常都是键盘输入); 这样就提供了一种按行读取文件的方法,并且可以使用sed和/或awk来对每一行进行分析。# read line:读取上一条标准输出#find /var/www/html/ -type f -exec md5sum {} \\; > /tmp/md5_www.logcheck_www () {md5sum -c /tmp/md5_www.log > /tmp/result_www.log[ ! -f /tmp/result_www.log ] && echo \"/tmp/result_www.log not exist.\" && exit 2exec < /tmp/result_www.logwhile read linedofile=`echo $line | awk -F\':\' \'{print $1}\'`result=`echo $line | awk -F\':\' \'{print $NF}\'`#echo $file#echo $result#sleep 2s[ ! $result = \"OK\" ] && action \"$file\" /bin/falsedone}main () {while truedoLANG=en #[ -f /etc/init.d/functions ] && . /etc/init.d/functions[ ! -f /tmp/md5_www.log ] && echo \"/tmp/md5_www.log not exist.\"&& exit 1check_wwwaction \"Alii check done.\" /bin/truesleep 10sdone}main
6、监控 MySQL 主从同步
- 监控 MySQL 主从同步是否异常,如果异常,则发送短信或者邮件给管理员。
- 提示:如果没主从同步环境,可以用下面文本放到文件里读取来模拟
- 阶段 1:开发一个守护进程脚本每 30 秒实现检测一次。
- 阶段 2:如果同步出现如下错误号(1158,1159,1008,1007,1062),则跳过错误。
- 阶段 3:请使用数组技术实现上述脚本(获取主从判断及错误号部分)
#!/bin/bashport=3306error=(1158 1159 1008 1007 1062)MysqlCmd1=\"mysql -h192.168.4.52 -uroot -p123456 -e\"MysqlCmd2=\"mysql -h192.168.4.52 -uroot -p123456 -e \'show slave status\\G\' | egrep \'_Running|Last_Errno|Behind_Master\' |awk \'{print \\$NF}\'\"is_run() {[ `lsof -i:$port |wc -l` -lt 2 ] && {echo \"mysql is stop\"exit 1}}mysql_status() {array=(`echo $MysqlCmd2 | bash`)}judge_error() {for i in ${error[*]}doif [ \"${array[2]}\" == \"$i\" ];then${MysqlCmd1} \"stop slave;SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;start slave;\"elseecho \"mysql is failed,error id is ${array[2]}\"fidone}judge_status() {mysql_statusecho ${array[*]}if [ \"${array[0]}\" == \"Yes\" -a \"${array[1]}\" == \"Yes\" -a \"${array[3]}\" == \"0\" ];thenecho \"Mysql slave is ok\"elsejudge_error #${array[2]}fi}main() {while truedois_runjudge_statussleep 3done}main
7、解决DOS攻击
- 用至少两种方法实现!写一个脚本解决 DOS 攻击生产案例