shell学习笔记(3)
一、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]#
相关文章