shell学习笔记(3)

2023-01-31 02:01:36 shell 学习笔记

一、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]# 

相关文章