shell学习笔记(3)

发布时间:2019-08-24 09:32:10编辑:auto阅读(1625)

    if

    一、if基础

    1、单分支

    1.1 语法

    if语句语法
        单分支结构语法:
        if [条件]; then
            指令
        fi
        或
        if  [条件]
            then
                指令
        fi

    1.2 例子

    [root@master4 day4]# cat if-single1.sh 
    #!/bin/sh
    #功能:单分支if结构整数比较,用-lt格式例子
    #created by xsz
    #date:20180107
    
    if [ 10 -lt 12 ]
        then
        echo "Yes,10 is less than 12"
    fi
    [root@master4 day4]# sh if-single1.sh 
    Yes,10 is less than 12
    
    传参方方式:
    [root@master4 day4]# cat if02.sh 
    #/bin/sh
    if [ $1 -lt $2 ]
        then
        echo "Year,$1 is less than $2"
    fi
    
    read接收方式:
    [root@master4 day4]# cat if03.sh 
    #/bin/sh
    read -t 10 -p "please input two number:" num1 num2
    if [ $num1 -lt $num2 ]
        then
        echo "Year,$num1 is less than $num2"
    fi
    
    以上脚本问题
    1、无法完整比较整数大小
    2、没有对参数的个数以及变量内容做判断

    1.3 范例3

    范例三(请思考):开发脚本实现如果/server/scripts下面存在if3.sh就输出到屏幕。
    注意:如果执行脚本后发现该if3.sh不存在,就自动创建这个if3.sh脚本。

    我的脚本:
    
    #!/bin/bash
    
    i=/server/scripts/if3.sh
    [ -e $i ] && cat $i && exit 0
    if [ $(sh $i 2> /dev/null;echo $?) != 0 ]
        then
        echo "$i is no exist,touching if03.sh..."
        echo "I am if03.sh" > $i
    fi
    
    老男孩的脚本1:
    #!/bin/sh
    dir=/server/scripts
    [ ! -d $dir ] && mkdir -p $dir
    file="if3.sh"
    if [ -f "$dir/$file" ]; then
        echo "$file is exist."
        exit 0
    fi
    touch $dir/$file
    
    同学:
    [root@master4 day4]# cat tiaojian.sh 
    #!/bin/sh
    dir=/server/scripts
    file=if3.sh
    cd $dir || mkdir -p $dir 
    [ ! -f "$file" ] && touch $file || echo $file

    1.4 内存告警脚本

    开发脚本判断系统内存大小,如果低于100M就邮件报警。测试报警成功后加入系统定时任务每3分钟执行一次检查。
    
    常见发送邮件方法:
    [root@master4 day4]# mail -s "tittle" hanzhaodiba@163.com < /etc/hosts
    [root@master4 day4]# echo "oldboy" | mail -s "tittle" hanzhaodiba@163.com
    
    安装发邮件:
    yum install -y sendmail
    
    sendmail启动慢原因
    1、主机名没有配置好
    [root@master4 day4]# uname -n
    master4.com
    10.201.106.134 master4 master4.com
    
    [root@master4 day4]# netstat -tanp | grep 25        
    tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      15622/sendmail
    
    解答:重视解决问题的过程
    1、先再命令行把条件取出来(我的是CentOS7)
    [root@master4 day4]# free -m | grep Mem | awk '{print $NF}'
    122
    
    2、编写脚本
    [root@master4 day4]# vim if04.sh
    
    #!/bin/sh
    
    current_mem=`free -m | grep Mem | awk '{print $NF}'`
    mem_chars="our sys mem is:$current_mem"
    if [ $current_mem -lt 200 ];then
        echo "$mem_chars" | mail -s "tittle" 635254246@qq.com
    fi
    
    [root@master4 day4]# sh -x if04.sh 
    ++ awk '{print $NF}'
    ++ grep Mem
    ++ free -m
    + current_mem=178
    + mem_chars='our sys mem is:178'
    + '[' 178 -lt 200 ']'
    + mail -s tittle 635254246@qq.com
    + echo 'our sys mem is:178'
    
    加入到定时任务:
    [root@master4 day4]# crontab -l
    #monitor memory
    */3 * * * * /bin/sh /server/scripts/day4/if04.sh > /dev/null 2>&1

    2、双分支

    2.1 比较两个整数大小(可用条件小写或者大于等于)

    我的脚本:
    [root@master4 day4]# cat if05.sh 
    #!/bin/sh
    
    if [ $1 -le $2 ];then
        if [ $1 -lt $2 ];then
        echo "$1 is less than $2"
        else
        echo "$1 is eq $2"
        fi
    else
        echo "$1 is big than $2"
    fi
    
    [root@master4 day4]# cat if-double01.sh 
    #!/bin/sh
    
    if [ $1 -lt $2 ];then
        echo "$1 < $2"
    else
        echo "$1 >= $2"
    fi
    [root@master4 day4]# sh if-double01.sh 4 5
    4 < 5
    [root@master4 day4]# sh if-double01.sh 2 2
    2 >= 2
    [root@master4 day4]# sh if-double01.sh 2 1
    2 >= 1

    3、多分支

    3.1 还是比较两个整数大小

    [root@master4 day4]# cat if-double02.sh 
    #!/bin/sh
    
    read -p "please input first number:" num1
    read -p "please input second number:" num2
    
    if [ $num1 -lt $num2 ];then
        echo "$num1 < $num2"
    elif [ $num1 -gt $num2 ];then
        echo "$num1 > $num2"
    else
        echo "$num1 = $num2"
    fi
    
    [root@master4 day4]# sh if-double02.sh 
    please input first number:4
    please input second number:3
    4 > 3
    [root@master4 day4]# sh if-double02.sh 
    please input first number:4
    please input second number:4
    4 = 4
    [root@master4 day4]# sh if-double02.sh 
    please input first number:4
    please input second number:5
    4 < 5
    
    老男孩脚本1:
    [root@master4 day4]# cat if-multi01.sh 
    #!/bin/sh
    
    if [ $1 -lt $2 ];then
        echo "$1 < $2"
    elif [ $1 -eq $2 ];then
        echo "$1 = $2"
    else
        echo "$1 > $2"
    fi
    
    解决命令行传参,不加参数,报错问题:
    [root@master4 day4]# cat judge-if-multi01-argv.sh 
    #!/bin/sh
    if [ $# -ne 2 ];then
        echo "$0 Usage method: num1 num2"
        exit 1
    fi
    if [ $1 -lt $2 ];then
        echo "$1 < $2"
    elif [ $1 -eq $2 ];then
        echo "$1 = $2"
    else
        echo "$1 > $2"
    fi
    
    解决输入非整数的问题:
    过滤出数字:
    [root@master4 day4]# echo "3434dkjfkddfd99" | sed 's#[a-z]##g'
    343499
    
    反过来,过滤数字,看字段是否为0。把数字去掉,长度为0,说明是数字
    [root@master4 day4]# echo "3434dkjfkddfd99" | sed 's#[0-9]##g'
    dkjfkddfd
    
    [root@master4 day4]# cat judge-if-multi01-argv.sh 
    #!/bin/sh
    if [ $# -ne 2 ];then
        echo "$0 Usage method: num1 num2"
        exit 1
    fi
    
    [ -n "`echo $1|sed 's#[0-9]##g'`" ] && {
        echo "num1 must be int."
        exit
    }
    
    [ -n "`echo $2|sed 's#[0-9]##g'`" ] && {
        echo "num2 must be int."
        exit
    }
    
    if [ $1 -lt $2 ];then
        echo "$1 < $2"
    elif [ $1 -eq $2 ];then
        echo "$1 = $2"
    else
        echo "$1 > $2"
    fi
    
    测试:
    [root@master4 day4]# sh judge-if-multi01-argv.sh nu3 34v 343
    judge-if-multi01-argv.sh Usage method: num1 num2
    [root@master4 day4]# sh judge-if-multi01-argv.sh nu3 34v
    num1 must be int.
    [root@master4 day4]# sh judge-if-multi01-argv.sh 43 34v
    num2 must be int.
    [root@master4 day4]# sh judge-if-multi01-argv.sh 43 3
    43 > 3
    [root@master4 day4]# sh judge-if-multi01-argv.sh 43 43
    43 = 43
    [root@master4 day4]# sh judge-if-multi01-argv.sh 43 53
    43 < 53

    4、判断字符串是否为数字的多种方法

    4.1 sed加正则表达式

    [ -n "`echo $num|sed 's/[0-9]//g'`"  ] && echo "第二个参数必须为数字" && exit 1
    条件表达式,大括号的用法:
    [ -n "`echo $num|sed 's/[0-9]//'`" ] && {
        echo "第二个参数必须为数字"
        exit 1
    }

    4.2 变量的子串替换加正则表达式

    [root@master4 day4]# num=521old521
    [root@master4 day4]# [ -z "`echo "${num//[0-9]/}"`" ] && echo 1 || echo 0
    0
    [root@master4 day4]# 
    
    这个结果说明前面的结果不为1,字符串非空,即有非数字字符
    
    ————————————————
    
    [root@master4 day4]# num=521
    [root@master4 day4]# [ -z "`echo "${num//[0-9]/}"`" ] && echo 1 || echo 0
    1
    
    这个结果说明前面的结果去掉数字后为1,即没有非数字字符

    4.3 变量的子串替换加正则表达式(特殊判断思路)

    思路:如果num长度不为0,并且把num中的非数字部分删除,然后看结果是不是等于num本身,如果两者都成立就是数字。
    
    [root@master4 day4]# num=123
    [root@master4 day4]# [ -n "$num" -a "$num" = "${num//[^0-9]/}" ] && echo "it is num"
    it is num
    [root@master4 day4]# num=1d3
    [root@master4 day4]# [ -n "$num" -a "$num" = "${num//[^0-9]/}" ] && echo "it is num" || echo "is not is num"
    is not is num
    [root@master4 day4]# 

    4.4 expr计算判断

    把变量和整数相加看是否成功执行:
    
    [root@master4 day4]# expr $1 + 0 > /dev/null 2>&1
    [root@master4 day4]# [ $? -eq 0 ] && echo int

    5、read读入方式判断整数大小

    我的脚本:
    #!/bin/sh
    read -p "please input first num:" num1
    read -p "please input second num:" num2
    
    [ -n "`echo $num1|sed 's#[0-9]##g'`" ] && {
        echo "num1 must be int."
        exit
    }
    
    [ -n "`echo $num2|sed 's#[0-9]##g'`" ] && {
        echo "num2 must be int."
        exit
    }
    
    if [ $num1 -lt $num2 ];then
        echo "$num1 < $num2"
    elif [ $$num1 -eq $$num2 ];then
        echo "$num1 = $num2"
    else
        echo "$num1 > $num2"
    fi
    
    老男孩的脚本1:
    [root@master4 day4]# vim read03.sh
    
    #!/bin/sh
    
    read -p "please input tow num:" a b
    
    expr $a + 0 > /dev/null 2>&1
    RETVAL1=$?
    expr $b + 0 > /dev/null 2>&1
    RETVAL2=$?
    
    [ "$RETVAL1" -eq 0 -a $RETVAL2 -eq 0 ] || {
        echo "argv1 and argv2 must be int."
        exit 2
    }
    
    if (( $a<$b ));then
        echo "$a<$b"
    elif [ $a -eq $b ];then
        echo "$a=$b"
    else
        echo "$a>$b"
    fi

    二、MySQL监控

    1、方法一

    1.1 监听端口

    我的脚本1:
    [root@master4 MySQL]# cat 01.sh 
    #!/bin/bash
    # pang duan mysqld starting
    
    if [ "`netstat -tan | grep 3306 | awk '{print $6}' | head -1`" == "LISTEN" ]; then
        echo "mysqld is starting"
    else
        echo "mysqld is stop.Now is starting mysqld service..."
        systemctl start mysqld.service
        pid=$(lsof -i:3306 | head -2 | grep mysqld | awk '{print $2}')
        echo "staring mysqld ok,the mysqld PID is $pid"  
    fi
    
    我的脚本2:
    [root@master4 MySQL]# cat 02.sh 
    #!/bin/bash
    # pang duan mysqld starting
    
    if [ "`systemctl status mysqld.service | grep Active | awk '{print $2}'`" == "active" ]; then
        echo "mysqld is starting"
    else
        echo "mysqld is stop.Now is starting mysqld service..."
        systemctl start mysqld.service
        pid=$(lsof -i:3306 | head -2 | grep mysqld | awk '{print $2}')
        echo "staring mysqld ok,the mysqld PID is $pid"  
    fi
    [root@master4 MySQL]# 
    
    老男孩的脚本1(这个方法有问题,进程被杀死,取得值为空,会报错):
    [root@master4 MySQL]# cat judgedb_by_port01.sh 
    #!/bin/sh
    
    port=`netstat -lnt | grep 3306 | awk -F '[ :]+' '{print $5}'`
    if [ $port -ne 3306 ];then
        echo "mysql is stoped"
        systemctl start mysqld
    fi
    
    老男孩的脚本1【改进版】(取netstat显示的行数):
    [root@master4 MySQL]# cat judgedb_by_port01.sh 
    #!/bin/sh
    
    portnum=`netstat -lnt | grep 3306 | wc -l`
    if [ $portnum -ne 1 ];then
        echo "mysql is stoped"
        systemctl start mysqld
    else
        echo "mysql is running"
    fi
    
    测试:
    [root@master4 MySQL]# sh judgedb_by_port01.sh 
    mysql is stoped
    [root@master4 MySQL]# sh judgedb_by_port01.sh 
    mysql is running
    [root@master4 MySQL]# 

    2、方法二

    2.0 监控端口和进程

    我的脚本1:
    [root@master4 MySQL]# cat judgedb_by_port01.sh 
    #!/bin/sh
    
    portnum=`netstat -lnt | grep 3306 | wc -l`
    pid=`ps -ed | grep mysqld | wc -l`
    if [ $portnum -ne 1 -o $pid -le 1 ];then
        echo "mysql is stoped"
        systemctl start mysqld
    else
        echo "mysql is running"
    fi
    
    [root@master4 MySQL]# bash -x judgedb_by_port01.sh 
    ++ wc -l
    ++ netstat -lnt
    ++ grep 3306
    + portnum=0
    ++ grep mysqld
    ++ wc -l
    ++ ps -ed
    + pid=0
    + '[' 0 -ne 1 -a 0 -le 1 ']'
    + echo 'mysql is stoped'
    mysql is stoped
    + systemctl start mysqld
    
    老男孩的脚本1:
    [root@master4 MySQL]# cat judgedb_by_port02.sh 
    #!/bin/sh
    
    portnum=`netstat -lnt | grep 3306 | wc -l`
    processsum=`ps -ef | grep mysql | grep -v grep | wc -l`
    if [[ $portnum -eq 1 || $processsum -eq 2 ]];then
        echo "mysql is running"
    else
        echo "mysql is stoped"
        echo "Staring MySQL..."
        systemctl start mysqld
    fi
    
    测试:
    [root@master4 MySQL]# sh -x judgedb_by_port02.sh 
    ++ wc -l
    ++ netstat -lnt
    ++ grep 3306
    + portnum=0
    ++ grep -v grep
    ++ wc -l
    ++ ps -ef
    ++ grep mysql
    + processsum=0
    + [[ 0 -eq 1 ]]
    + [[ 0 -eq 2 ]]
    + echo 'mysql is stoped'
    mysql is stoped
    + systemctl start mysqld
    [root@master4 MySQL]# 
    [root@master4 MySQL]# 
    [root@master4 MySQL]# sh -x judgedb_by_port02.sh 
    ++ wc -l
    ++ netstat -lnt
    ++ grep 3306
    + portnum=1
    ++ grep mysql
    ++ grep -v grep
    ++ ps -ef
    ++ wc -l
    + processsum=2
    + [[ 1 -eq 1 ]]
    + echo 'mysql is running'
    mysql is running
    [root@master4 MySQL]# 
    
    老男孩脚本2:
    [root@master4 MySQL]# cat judgedb_by_port03.sh 
    #!/bin/bash
    #function:check mysql status
    
    MySQLSTARTUP="systemctl start mysqld.service"
    DbProcessCount=`ps -ef | grep mysql | grep -v brep | wc -l`
    DbPortCount=`netstat -lnt | grep 3306 | wc -l`
    if [ $DbProcessCount -eq 2 ] && [ $DbPortCount -eq 1 ];then
        echo "MySQL is running"
    else
        $MySQLSTARTUP > /tmp/mysql.log
        sleep 10;
        DbProcessCount=`ps -ef | grep mysql | grep -v grep | wc -l`
        DbPortCount=`netstat -lnt | grep 3306 | wc -l`
        if [ $DbProcessCount -ne 2 ] || [ $DbPortCount -ne 1 ];then
        pkill mysqld > /dev/null 2>&1
        sleep 5
        pkill mysqld > /dev/null 2>&1
        sleep 5
        [ $DbProcessCount -eq 0 ] && MySQLSTARTUP >> /tmp/mysql.log
        [ $? -eq 0 ] && echo "mysql is started"
        fi
    
        mail -s "mysql restarted" xxxxxx@qq.com < /tmp/mysql.log
    fi

    2.2 转化脚本格式为UNIX模式

    [root@master4 MySQL]# dos2unix judgedb_by_port03.sh 
    dos2unix: converting file judgedb_by_port03.sh to Unix format ...

    3、方法三

    3.0 脚本测试连接

    我的脚本1:
    [root@master4 MySQL]# cat 03.sh 
    #!/bin/sh
    
    value=`mysql -uroot -p'root' -S /var/lib/mysql/mysql.sock -e "SELECT VERSION();" > /dev/null 2>&1;echo $?`
    portnum=`netstat -lnt | grep 3306 | wc -l`
    processsum=`ps -ef | grep mysql | grep -v grep | wc -l`
    if [[ $portnum -eq 1 && $processsum -eq 2 && value -eq 0 ]];then
        echo "mysql is running"
    else
        echo "mysql is stoped"
        echo "Staring MySQL..."
        systemctl start mysqld
        Version=`mysql -uroot -p'root' -S /var/lib/mysql/mysql.sock -e "SELECT VERSION();" | grep -v "()"`
        echo "The MySQL version is $Version"
    fi
    
    老男孩的脚本1:
    [root@master4 MySQL]# cp judgedb_by_port02.sh judgedb_by_mysql04.sh
    
    [root@master4 MySQL]# cat judgedb_by_mysql04.sh
    #!/bin/sh
    mysql -uroot -proot -S /var/lib/mysql/mysql.sock -e "SELECT VERSION();" >/dev/null 2>&1
    if [[ $? -eq 0 ]];then
        echo "mysql is running"
    else
        echo "mysql is stoped"
        echo "Staring MySQL..."
        systemctl start mysqld
    fi
    
    异地连接,使用-h IP

    4、方法四

    4.1 通过php/java程序监控MySQL

    三、监控nginx或apache

    1、

    1.1 查看nginx是否运行

    [root@master4 ~]# netstat -tan | grep 80
    tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     
    tcp6       0      0 :::80                   :::*                    LISTEN     
    [root@master4 ~]# lsof -i :80
    
    [root@master4 ~]# ps -ef | grep nginx
    
    [root@node3 ~]# curl -I 10.201.106.134
    
    [root@node3 ~]# wget 10.201.106.134
    
    [root@node3 ~]# curl -o /dev/null -s -w "%{http_code}" 10.201.106.134
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100  3700  100  3700    0     0   695k      0 --:--:-- --:--:-- --:--:--     0
    
    curl -s  静默显示
    
    [root@node3 ~]# nmap 10.201.106.134 -p 80 | grep open | wc -l
    1
    
    [root@node3 ~]# curl -o /dev/null -s -w %{http_code} http://10.201.106.134
    200[root@node3 ~]# 
    
    [root@node3 ~]# curl -s -I http://10.201.106.134 | sed -n '1p' | cut -d " " -f2
    200

    1.2 namp判断nginx是否启动

    [root@master4 nginx]# vim judgeweb_by_port01.sh 
    
    #!/bin/sh
    
    portnum=`nmap 10.201.106.134 -p 80 | grep open | wc -l`
    if [ $portnum -ne 1 ];then
        echo "nginx is stoped"
        systemctl start nginx
    else
        echo "nginx is running"
    fi

    1.3 wget

    [root@master4 nginx]# vim judgeweb_by_wget-url02.sh 
    
    #!/bin/sh
    
    wget -T 15 -q --spider http://10.201.106.134
    if [ $? -ne 0 ];then
        echo "nginx is stoped"
        systemctl start nginx
    else
        echo "nginx is running"
    fi

    1.4 获取状态码判断

    [root@master4 nginx]# vim judgeweb_by_curl-code03.sh 
    
    #!/bin/sh
    
    httpcode=`curl -o /dev/null -s -w %{http_code} http://10.201.106.134`
    if [ "$httpcode" != "200" ];then
        echo "nginx is stoped"
        systemctl start nginx 
    else
        echo "nginx is running"
    fi
    
    [root@master4 nginx]# pkill nginx
    [root@master4 nginx]# sh judgeweb_by_curl-code03.sh 
    nginx is stoped
    [root@master4 nginx]# sh judgeweb_by_curl-code03.sh 
    nginx is running
    [root@master4 nginx]# 

关键字