AI智能
改变未来

SHELL脚本-基础概念(入门级)

目录

  • 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
  • 十、Sed
    • 1、格式
    • 2、基本应用
    • 3、实际使用
  • 十一、awk
    • 1、格式
    • 2、条件的使用
    • 2.1、正则
    • 2.2、字符、数值比较
    • 2.3、逻辑符号:&&、||
    • 2.4、计算
  • 3、工作流程的控制
    • 3.1、if
    • 3.2、BEGIN、END
  • 4、数组
  • awk细节注意点
  • 应用案例
    • 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 攻击生产案例
    赞(0) 打赏
    未经允许不得转载:爱站程序员基地 » SHELL脚本-基础概念(入门级)