您的位置:首页 > 运维架构 > Shell

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

2020-06-06 05:00 351 查看

目录

  • 二、变量
  • 三、运算
  • 四、条件测试
  • 五、判断结构
  • 六、循环结构
  • 七、函数
  • 八、字符串的处理
  • 九、正则
  • 十、Sed
  • 十一、awk
  • 3、工作流程的控制
  • 4、数组
  • awk细节注意点
  • 应用案例
  • 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/bash
    
    echo $1		#脚本后第1个参数
    echo $2		#脚本后第2个参数
    echo $3		#脚本后第3个参数
    ... ...
    echo $10	#脚本后第10个参数

    4、预定义变量

    #!/bin/bash
    
    echo $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+1
    let b=c+d
    
    变量的自增减:
    let a=a-1	相当于	  let a--
    let a=a+1	相当于	  let a++
    let a=a+2			let a+=2
    let a=a-2			let a-=2
    let a=a*2			let a*=2
    let a=a/2			let a/=2
    let a=a%2			let a%=2

    4、bc

    bc 常用于小数的计算
    echo "1.2+3.5" | bc
    echo "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/bash
    case $1 in
    redhat)
    echo "fedora";;
    fedora)
    echo "redhat";;
    *)                                              //默认输出脚本用法
    echo "用法: $0 {redhat|fedora}"
    esac

    六、循环结构

    1、for循环

    • 有限的循环,循环的次数和值有关
    #基本结构:
    for 变量名 in 循环值1、2、3....
    do
    命令
    done
    
    ----------------------------
    例1:
    #!/bin/bash
    for i in {1..10}
    do
    echo $i
    done
    ----------------------------
    例2:
    #!/bin/bash
    a=10
    for i in `seq $a`	#这里有变量时不能用大括号{}
    do
    echo $i
    done

    2、while循环

    • 无限循环(死循环)
    #基本结构:
    while 条件测试
    do
    命令
    done
    -------------------------------------------
    
    #!/bin/bash
    x=$[RANDOM%100]		#RANDOM:生成随机数。
    y=0
    while :			#这里':'是指任何条件都成立
    do
    let y++
    read -p "猜数(0-99):" n
    if [ $n -gt $x ];then
    echo "大了"
    elif [ $n -lt $x ];then
    echo "小了"
    else
    echo "对了"
    echo "共猜了$y次"
    fi
    done

    3、循环的控制

    • exit:退出脚本
    • break:终止循环,执行循环之后的任务
    • continue:终止当前循环,继续下一次循环

    七、函数

    • 函数一般用在脚本里面,对于一些经常性用到的命令进行一个定义,然后在脚本中可以直接调用。
    # 格式1:
    
    function 函数名 {
    命令序列1
    命令序列2
    ... ...
    }
    
    # 格式2:
    函数名 () {
    命令序列
    ... ...
    }

    例:

    # 使用函数编写方便调用不同颜色字体的脚本:
    #!/bin/bash
    cecho (){
    echo -e "\033[$1m$2\033[0m"					# 定义了一个函数命令
    }
    cecho 31 ABCDEFG							# 调用函数命令
    cecho 32 ABCDEFG
    cecho 33 ABCDEFG
    cecho 34 ABCDEFG
    cecho 35 ABCDEFG
    cecho 36 ABCDEFG
    cecho 37 ABCDEFG
    
    # 炸弹脚本
    #!/bin/bash
    abc(){
    abc|abc &
    }
    abc

    八、字符串的处理

    1、截取

    # 格式:
    ${变量名:起始位置:长度}		# 起始位置的计算从0开始
    
    # 例:
    b=65498165
    echo ${b:3:4}		# 截取变量b,从第4位开始截取4位
    echo ${b::4}		# 起始为0时可省略0
    
    # 应用:编写随机获取6位密码的脚本
    #!/bin/bash
    x=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
    for i in {1..6}
    do
    n=${RANDOM%62}
    p=${x:n:1}
    pass=$p$pass
    done
    echo $pass

    2、替换

    # 格式:
    ${变量名/旧/新}
    
    # 例:
    b=1802874632
    echo ${b/1/a} 		# 将 1 替换为 a
    echo ${b/8/a} 		# 将 8 替换为 a
    echo ${b//8/a} 		# 将所有 8 替换为 a
    echo ${b/0/} 		# 将数字 0 替换为空,相当于删除

    3、删除(掐头去尾)

    # 格式:
    ${变量名#*关键词} 			# 从左往右删除 掐头
    # 例
    a="root:x:0:0:root:/root:/bin/bash"
    echo ${a#root} 				# 删除到第一个 root
    echo ${a##*root} 			# 删除到最后一个 root,以及此 root 左边所有
    echo ${a##*/} 				# 删除到最后一个/,以及此/左边所有
    echo ${a#*:root} 			# 删除:root,以及左边所有
    --------------------------------------------
    # 格式
    ${变量名%关键词*} 			# 从右往左删除 去尾
    # 例
    echo ${a%bash} 				# 从右往左删除到 bash
    echo ${a%root*} 			# 从右往左删除到第一个 root,以及 root 右边所有
    echo ${a%/*} 					# 从右往左删除到第一个/,以及/右边所有
    echo ${a%%/*} 				# 从右往左删除到最后一个/,以及/右边所有
    
    --------------------------------------------------------------------
    # 利用字符串删除功能,编写批量修改文件扩展名的脚本:
    #!/bin/bash
    for i in `ls *.txt` 首先找到修改目标
    do
    n=${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/bash
    read -p "请输入用户名:" u
    useradd $u
    read -p "请输入密码:" p
    echo ${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 或者 n
    grep [^in] user 						# 搜索除了字母 i 或者 n 以外所有的
    grep "."  user							搜索任意单个字符。包括空格,但不包括空行。
    grep ".*"  user 						搜索任意。包括空行。
    grep "ro*t" user 						# 搜索r?t,r与t之间任意个o
    
    grep "0:\{2\}" user 				# 搜索 0::
    grep "\(0:\)\{2\}" user			# 搜索 0:0:
    • 扩展正则
    • grep -E 或 egrep
    grep -E "ro+t" user
    egrep "ro+t" user
    
    grep -E "bi?n" user
    egrep "bi?n" user
    
    grep -E "ro{2,4}t" user			# 搜索ro?t,其中o出现2到4次
    grep -E "ro|in" user 				# 搜索ro或in
    grep -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替换成abc
    sed 's/xml/abc/3'  a.txt			# 将每行中的第3个xml替换成abc
    sed 's/xml/abc/g'  a.txt			# 将全部xml替换成abc
    sed 's/xml//g'	a.txt					# 将全部xml替换成空,即删除
    
    sed 's/\/bin\/bash/\/sbin\/sh/' user		# 将/bin/bash 替换成 /sbin/sh
    sed 's#/bin/bash#/sbin/sh'  user
    sed 's!/bin/bash!/sbin/sh'  user
    sed '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/bash
    u=`sed -n '/bash$/s/:.*//p' /etc/passwd`			# 找到bash用户,并把名字存入变量b
    for i in $u
    do
    x=`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.txt
    awk '$3<5' a.txt				# 输出第3列小于5的行
    awk '$3=="5"' a.txt			# 输出第3列的字符等于0的行。

    2.3、逻辑符号:&&、||

    # 逻辑符号一般配合其它的条件因素进行使用。
    awk '$2<10 && $2>5' a.txt
    awk '$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 0
    1 11
    2 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_log
    4  127.0.0.1
    17 192.168.4.5
    13 192.168.4.110
    .. ..
    
    # 对访问量排序排名:
    [root@svr5 ~]# awk  '{ip[$1]++} END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log | sort -nr
    17 192.168.4.5
    13 192.168.4.110
    4 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/bash
    ip=`ifconfig eth0 | awk '/inet /{print $2}'`
    echo "本地IP地址是:"$ip
    cpu=`uptime | awk '{print $NF}'`
    #awk中NF为当前行的列数,$NF是最后一列
    echo "本机CPU最近15分钟的负载是:"$cpu
    net_in=`ifconfig eth0 | awk '/RX p/{print $5}'`
    echo "入站网卡流量为:"$net_in
    net_out=`ifconfig eth0 | awk '/TX p/{print $5}'`
    echo "出站网卡流量为:"$net_out
    mem=`free | awk '/Mem/{print $4}'`
    echo "内存剩余容量为:"$mem
    disk=`df | awk '/\/$/{print $4}'`
    echo "根分区剩余容量为:"$disk
    user=`cat /etc/passwd |wc -l`
    echo "本地账户数量为:"$user
    login=`who | wc -l`
    echo "当前登陆计算机的账户数量为:"$login
    process=`ps aux | wc -l`
    echo "当前计算机启动的进程数量为:"$process
    soft=`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/bash
    awk '/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/bash
    A=$(sed -n '/bash$/s/:.*//p' /etc/passwd)             # 提取符合条件的账号记录
    for i in  $A                                          # 遍历账号记录
    do
    pass1=$(grep $i /etc/shadow)
    pass2=${pass1#*:}
    pass=${pass2%%:*}
    echo  "$i   --> $pass"
    done
    #/bin/bash
    A=$(awk -F:  '/bash$/{print $1}' /etc/passwd)        # 提取符合条件的账号记录
    for i in $A
    do
    grep $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.cn
    Port=80
    
    check_web() {
    [ -f /etc/init.d/functions ]&& . /etc/init.d/functions
    
    if [ "`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" ];then
    
    action "$url $Port" /bin/true					# 打印指定内容,并提示是[OK]
    else
    action "$url $Port /bin/false"				# 打印指定内容,并提示是[FAILED]
    fi
    }
    
    main() {
    while true
    do
    check_web
    sleep 1m
    done
    }
    
    main

    4、监控 db 服务

    • 监控 db 服务是否正常,不低于 3 种监控策略。要求间隔 1 分钟,持续监控。
    #!bin/bash
    Port=3306
    user=
    pw=
    IP=
    
    check_db() {
    [ -f /etc/init.d/functions ] && . /etc/init.d/functions
    if [ `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 ];then
    
    action "MySQL $Port online" /bin/true
    else
    action "MySQL $Port down" /bin/false
    fi
    }
    main() {
    while true
    do
    check_db
    sleep 1s
    done
    }
    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.log
    
    check_www () {
    md5sum -c /tmp/md5_www.log > /tmp/result_www.log
    [ ! -f /tmp/result_www.log ] && echo "/tmp/result_www.log not exist." && exit 2
    
    exec < /tmp/result_www.log
    while read line
    do
    file=`echo $line | awk -F':' '{print $1}'`
    result=`echo $line | awk -F':' '{print $NF}'`
    #echo $file
    #echo $result
    #sleep 2s
    [ ! $result = "OK" ] && action "$file" /bin/false
    done
    }
    
    main () {
    while true
    do
    LANG=en																		#
    [ -f /etc/init.d/functions ] && . /etc/init.d/functions
    [ ! -f /tmp/md5_www.log ] && echo "/tmp/md5_www.log not exist."&& exit 1
    check_www
    action "Alii check done." /bin/true
    sleep 10s
    done
    }
    
    main

    6、监控 MySQL 主从同步

    • 监控 MySQL 主从同步是否异常,如果异常,则发送短信或者邮件给管理员。
    • 提示:如果没主从同步环境,可以用下面文本放到文件里读取来模拟
    • 阶段 1:开发一个守护进程脚本每 30 秒实现检测一次。
    • 阶段 2:如果同步出现如下错误号(1158,1159,1008,1007,1062),则跳过错误。
    • 阶段 3:请使用数组技术实现上述脚本(获取主从判断及错误号部分)
    #!/bin/bash
    
    port=3306
    error=(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[*]}
    do
    if [ "${array[2]}" == "$i" ];then
    ${MysqlCmd1} "stop slave;SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;start slave;"
    else
    echo "mysql is failed,error id is ${array[2]}"
    fi
    done
    }
    
    judge_status() {
    mysql_status
    echo ${array[*]}
    if [ "${array[0]}" == "Yes" -a "${array[1]}" == "Yes" -a "${array[3]}" == "0" ];then
    echo "Mysql slave is ok"
    else
    judge_error  #${array[2]}
    fi
    }
    
    main() {
    while true
    do
    is_run
    judge_status
    sleep 3
    done
    }
    
    main

    7、解决DOS攻击

    • 用至少两种方法实现!写一个脚本解决 DOS 攻击生产案例
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: