shell实例100例《九》

8一、题目要求   :   监控磁盘php

阿里云的机器,今天收到客服来的电话,说服务器的磁盘io很重。因而登陆到服务器查看,并无发现问题,因此怀疑是间歇性地。正要考虑写个脚本的时候,幸运的抓到了一个线索,形成磁盘io很高的幕后黑手是mysql。此时去show processlist,但未发现有问题的队列。原来只是一瞬间。只好继续来写脚本,思路是,每5s检测一次磁盘io,当发现问题去查询mysql的processlist。java

【核心要点】python

iostat -xd 1 5 ,主要看%util  ;-xd  :只查看磁盘信息。mysql

参考答案

#!/bin/bash
#这个脚本用来监控磁盘IO
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-12

if ! while iostat &>/dev/null
then
    yum install -y sysstat
fi

while :
do
    t=`date +%T`
    iostat -xd 1 5 |grep '^sda'> /tmp/io.log
    sum=`awk '{sum=sum+$NF} END {print sum}' /tmp/io.log`
    a=`echo "scale=2;$sum/5"|bc`
    b=`echo $a|cut -d . -f 1`
    if [ $b -gt 90 ]
    then
	mysql -uroot -pxxxx -e "show processlist" > mysql_$t.log
    fi
    sleep 1
done

实例 :linux

查看磁盘的读写速度。%util越大,说明磁盘越忙。ios

查看平均磁盘读写速率git

查看磁盘sda的读写速度,查看最后一列。github

将磁盘sda的读写速度写入到/tmp/io.log。取最后一列使用“$NF”,显示磁盘的读写速度是0.02sql

修改磁盘读写速度,用于测试。shell

6.92除以5,求磁盘平均读写速度。

取一位整数

执行脚本,查看结果

 

注意  :   

yum install -y sysstat                #安装查看io的命令软件包

if ! while iostat &>/dev/null                 #查看iostat有没有安装,若是没有,执行下面的任务。

t=`date +%T`                           #显示当前系统时间
iostat -xd 1 5 |grep '^sda'> /tmp/io.log            #将磁盘sda的读写速度写入到/tmp/io.log。
sum=`awk '{sum=sum+$NF} END {print sum}' /tmp/io.log`           #将磁盘sda的读写速度写入到/tmp/io.log。取最后一列使用“$NF”,写入到/tmp/io.log。


a=`echo "scale=2;$sum/5"|bc`                   #除以5,保留2位数字
b=`echo $a|cut -d . -f 1`                 #取一位整数
if [ $b -gt 90 ]                     #查看gt的值是否大于90
 

mysql -uroot -pxxxx -e "show processlist" > mysql_$t.log     #若是当发现问题去查询mysql的processlist。,并写入到mysql_$t.log日志里面

 

 

8二、题目要求  :  查看tomcat日志

写一个截取tomcat catalina.out日志的脚本 tomcat实例t1-t4

# find  /opt/TOM/   -name  catalina.out
/opt/TOM/t1/logs/catalina.out
/opt/TOM/t3/logs/catalina.out
/opt/TOM/t4/logs/catalina.out
/opt/TOM/t2/logs/catalina.out

要求:

  1. 这个脚本能够取tomcat实例t1-t4的日志
  2. 这个脚本能够自定义取日志的起始点 ,好比取今天早上10点以后到如今的数据
  3. 这个脚本能够自定义取日志的起始点和终点,好比取今天早上9点到晚上8点的数据 catalina.out 日志内容
Oct 29, 2018 01:52:24 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Oct 29, 2018 01:52:24 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Oct 29, 2018 01:52:24 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 2102 ms

【核心要点】

参考答案

#!/bin/bash
#这个脚本用来查看Tomcat日志
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-12

LANG=en
logfile="/opt/TOM/$1/logs/catalina.out"

#将当天的英文月、数字日期、数字年做为变量赋值给d_mdy
d_mdy=`date "+%b %d, %Y"`

#判断参数个数
if [ $# -ne 2 ] && [ $# -ne 3 ]
then
    echo "你提供的参数个数不对,请提供2个或者3个参数。例:sh $0 t1 08:01:00 14:00:00" 
    exit 1
fi

#判断第一个参数是否符合要求
if ! echo $1|grep -qE '^t1$|^t2$|^t3$|^t4$'
then
    echo "第一个参数必须是t一、t二、t3或t4"
    exit 1
fi 

#判断时间有效性
judge_time()
{
    date -d "$1" +%s &>/dev/null
    if [ $? -ne 0 ]
    then
        echo "你提供的时间$1格式不正确"
        exit 1
    fi
}

#将24小时制时间转换为12小时
tr_24_12()
{
    date -d "$1" +%r
}

#判断提供的时间点是否在日志中出现
judge_time_in_log()
{
    if ! grep -q "$d_mdy $(tr_24_12 $1)" $logfile
        then
            echo "你提供的时间$1在日志$logfile中未曾出现,请换一个时间点"
            exit 1
        fi    
}

#判断第2个参数是否合法
judge_time $2

#判断起始时间点是否出如今日志里
judge_time_in_log $2

#若是提供第3个参数
if [ $# -eq 3 ]
then
    #判断第3个参数是否合法
    judge_time $3

    #判断起始时间是否早于结束时间
    t1=`date -d "$2" +%s`
        t2=`date -d "$3" +%s`
        if [ $t2 -lt $t1 ]
        then
            echo "你提供的时间$2比$3要晚,应该把早的时间放到前面"
            exit
        fi

        #判断提供的结束时间点是否出如今日志中
        judge_time_in_log $3
fi


#取起始时间所在行行号
begin_n=`grep -n "$d_mdy $(tr_24_12 $2)" $logfile|head -1|awk -F ':' '{print $1}'`

#取结束时间所在行行号,并用sed截取日志内容
if [ $# -eq 3 ]
then
    n=`grep -n "$d_mdy $(tr_24_12 $3)" $logfile|tail -1|awk -F ':' '{print $1}'`
    #结束日期所在行的下一行才是日志的内容
    end_n=$[$n+1]
    sed -n "$begin_n,$end_n"p $logfile
else
    sed -n "$begin_n,$"p $logfile
fi

实例 :

查看系统时间,是否和tomcat日志里面的时间同样。

将24小时时间制转换成12小时时间制,和Tomcat日志的时间格式同样,便于观察。

 

执行脚本,查看结果

注意 “:

date -d "$1" +%s &>/dev/null               #将用户输入的参数,写入到/dev/null 中,-d测试,$1表示用户输入的时间

if [ $# -ne 2 ] && [ $# -ne 3 ]                 #提供的参数 不是2,也不是3时。提示用户。

if ! grep -q "$d_mdy $(tr_24_12 $1)" $logfile               #将24小时时间制转换成12小时时间制,grep -p检查时间格式是否是和日志中的同样。

 

 

8三、题目要求   :   打印城市名字

写一个脚本让用户输入多个城市的名字(能够是中文),要求很多于5个,而后把这些城市存到一个数组里,最后用for循环把它们打印出来。

【核心要点】

赋值数组 : arry=(1 2 a b c)

打印数组 : echo ${arry[@]}

参考答案

#!/bin/bash
#这个脚本用来打印城市名字
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-12

read -p "输入很多于5个城市的名字,用空格分隔开。" name

n=`echo $name|awk '{print NF}'`

if [ $n -lt 5 ]
then
    echo "请输入至少5个城市的名字."
    exit
fi

city=($name)

for i in `seq 0 $[${#city[@]}-1]`
do
    echo ${city[$i]}
done

实例 :

打印数组

查看数组的循环,发现是从0开始的。

数组的赋值 ;打印数组的值 ; 统计数组的个数 ;针对个别元素。

执行脚本,查看结果。

注意  : 

n=`echo $name|awk '{print NF}'`                    #名字之间,用空格隔开。

if [ $n -lt 5 ]                            #$n的值小于5,

for i in `seq 0 $[${#city[@]}-1]`             #打印用户输入的城市名,由于数组的循环是从0开始的,因此要减一。

 

 

8四、题目要求  :   代码上线

需求背景是: 一个业务,有3台服务器(A,B,C)作负载均衡,因为规模过小目前并未使用专业的自动化运维工具。有新的需求时,开发同事改完代码会把变动上传到其中一台服务器A上。可是其余2台服务器也须要作相同变动。

写一个shell脚本,把A服务器上的变动代码同步到B和C上。 其中,你须要考虑到不须要同步的目录(假若有tmp、upload、logs、caches)

【核心要点】

rsync同步

密钥认证或者expect脚本

参考答案

#!/bin/bash
#这个脚本用来代码上线
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-12

dir=/data/wwwroot/www.aaa.com
B_IP=1.1.1.1
C_IP=2.2.2.2

rs()
{
    rsync -azP --exclude="logs" \
    --exclude="tmp" --exclude="upload" \
    --exclude="caches" $dir/ $1:$dir/
}

read -p "该脚本将会把本机的$dir下的文件同步到$B_IP和$C_IP上,是否要继续?y|n" c

case $c in 
    y|Y)
	rs B_IP
	rs C_IP
	;;
    n|N)
	exit
 	;;
    *)
	echo "你只能输入y或者n."
        ;;
esac

 

注意  :

 dir=/data/wwwroot/www.aaa.com                 #假如a ,b,c机器的变动代码须要同步的目录都是同样。

 rsync -azP --exclude="logs" \
    --exclude="tmp" --exclude="upload" \
    --exclude="caches" $dir/ $1:$dir/              #把A服务器上的变动代码同步到B和C上,排除的目录
tmp、upload、logs、caches。  $dir/ $1:$dir/表示$dir同步到b机器下的$dir目录下,$1是b机器的IP

 

8五、题目要求  :    统计并发量

需求背景:

须要统计网站的并发量,并绘图。 说明: 只须要写出shell脚本便可,不用关心zabbix配置。

假设日志路径 /data/logs/www.aaa.com_access.log

日志格式以下:

112.107.15.12 - [07/Nov/2018:09:59:01 +0800] www.aaa.com "/api/live.php" 200"-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)"

【核心要点】

查看日志中1秒内的日志数量,即并发数(每秒请求多少次)

参考答案

#!/bin/bash
#这个脚本用来计算网站并发量
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-12

LANG=en
t=`date -d "-1 second" +%d/%b/%Y:%`
log=/data/logs/www.aaa.com_access.log

tail -1000 $log |grep -c "$t"

实例 :

获取上一秒的时间。%b : 做用是显示月份。

获取上一秒的时间,与日志显示的时间一致。

 

 

执行脚本,查看结果

注意  : 

t=`date -d "-1 second" +%d/%b/%Y:%`                 #   求上一秒的日志时间
log=/data/logs/www.aaa.com_access.log                 #访问日志,经过访问日志,计算网站的并发量

tail -1000 $log |grep -c "$t"                         #统计最后一千条并发量日志,并截取到日志时间

 

 

8六、题目要求  :   关闭服务

在centos6系统里,咱们可使用ntsysv关闭不须要开机启动的服务,固然也可使用chkconfig工具来实现。

写一个shell脚本,用chkconfig工具把不经常使用的服务关闭。脚本须要写成交互式的,须要咱们给它提供关闭的服务名字。

【核心要点】

chkconfig --list

参考答案

#!/bin/bash
#这个脚本用来关闭服务
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-14

LANG=en

while :
do
    chkconfig --list 2>/dev/null|grep '3:on' |awk '{print $1}' > /tmp/on_sev.txt
    echo -e "\033[32m系统里开启了这些服务: \033[0m"
    cat /tmp/on_sev.txt
    echo
    read -p "Please select a service from this list: " s

    if ! grep -qw "$s" /tmp/on_sev.txt
    then
	echo -e "\033[31m你提供的服务名并未开启.\033[0m"
	continue
    fi
    chkconfig $s off
    break
done

实例 :

查看服务列表

列出开启的服务,并显示在一列。

给字体添加颜色

执行脚本,查看结果

注意  : 

chkconfig --list 2>/dev/null|grep '3:on' |awk '{print $1}' > /tmp/on_sev.txt             #列出全部的on服务,
echo -e "\033[32m系统里开启了这些服务: \033[0m"           #

 

 if ! grep -qw "$s" /tmp/on_sev.txt              #查看$s,是否在/tmp/on_sev.txt  ,不存在,就提示用户。

chkconfig $s off                         #关闭不须要开机启动的$s服务。

 

8七、题目要求   :   完全关闭tomcat服务

在生产环境中,常常遇到tomcat没法完全关闭,也就是说用tomcat自带shutdown.sh脚本没法将java进程彻底关掉。因此,须要借助shell脚本,将进程杀死,而后再启动。

写一个shell脚本,实现上述功能。完全杀死一个进程的命令是 kill -9 pid。

【核心要点】

kill -9 pid

参考答案

#!/bin/bash
#这个脚本用来完全杀死Tomcat进程
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-14

dir=/usr/local/tomcat/bin/

java_pc()
{
    pgrep java|wc -l
}

	
cd $dir
./shutdown.sh

count=0

while [ $count -lt 5 ]
do
    n=`java_pc`
    if [ $n -gt 0 ]
    then
	killall java
	count=$[$count+1]
	sleep 1
    else
	break
    fi
done
    
n=`java_pc`
if [ $n -gt 0 ]
then 
    killall -9 java
fi

n=`java_pc`
if [ $n -gt 0 ]
then
    echo "Tomcat没法强制杀死。"
    exit
fi

cd $dir
./startup.sh

实例 :

执行脚本,查看结果

 

注意  : 

pgrep java|wc -l              #把java方面的服务和进程行数,都统计出来。

while [ $count -lt 5 ]               #当他关闭的次数小于5

if [ $n -gt 0 ]                        #当$n大于0。

 

 

8八、题目要求   :    去掉文件名后缀

至少用两种方法,批量把当前目录下面全部文件名后缀为.bak的后缀去掉,好比1.txt.bak去掉后为1.txt

【核心要点】

方法一 :用sed把文件名结尾的.bak去掉

方法二 :awk截取去掉后缀的部分,复制变量

参考答案

#!/bin/bash
#这个脚本用来去掉文件名后缀
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-14

for f in `ls -d  ./*.bak `
do
#    mv $f  `echo $f|sed 's/.bak$//'`
    f1=`echo $f|awk -F '.bak$' '{print $1}' `
    mv $f $f1
done

实例 :

查看目录下的.bak的文件

执行脚本,查看结果

脚本生成的1。1

注意  : 

for f in `ls -d  ./*.bak `                            #表示目录下的.bak的文件
mv $f  `echo $f|sed 's/.bak$//'`                    #用sed把文件名结尾的.bak去掉
f1=`echo $f|awk -F '.bak$' '{print $1}' `                 #awk截取去掉后缀的部分,复制变量,打印第一行。

 

8九、题目要求   :     检查域名是否到期

写一个shell脚本,查询指定域名的过时时间,并在到期前一周,天天发一封提醒邮件。

【核心要点】

能够在Linux下使用命令“whois域名”,如“whois aplelearn.com” ,来获取该域名的一些信息

参考答案

#!/bin/bash
#这个脚本用来检查域名是否到期
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-14

mail_u=admin@admin.com
#当前日期时间戳,用于和域名的到期时间作比较
t1=`date +%s`

#检测whois命令是否存在,不存在则安装jwhois包
is_install_whois()
{
    which whois >/dev/null 2>/dev/null
    if [ $? -ne 0 ]
    then
	yum install -y epel-release
        yum install -y jwhois
    fi
}

notify()
{
    #e_d=`whois $1|grep 'Expiry Date'|awk '{print $4}'|cut -d 'T' -f 1`
    e_d=`whois $1|grep 'Expiration'|tail -1 |awk '{print $5}' |awk -F 'T' '{print $1}'`
    #若是e_d的值为空,则过滤关键词'Expiration Time'
    if [ -z "$e_d" ]
    then
        e_d=`whois $1|grep 'Expiration Time'|awk '{print $3}'`
    fi
    #将域名过时的日期转化为时间戳
    e_t=`date -d "$e_d" +%s`
    #计算一周一共有多少秒
    n=`echo "86400*7"|bc`
    e_t1=$[$e_t-$n]
    e_t2=$[$e_t+$n]
    if [ $t1 -ge $e_t1 ] && [ $t1 -lt $e_t ]
    then
        python mail.py  $mail_u "Domain $1 will  to be expired." "Domain $1 expire date is $e_d."
    fi
    if [ $t1 -ge $e_t ] && [ $t1 -lt $e_t2 ]
    then
        python mail.py $mail_u "Domain $1 has been expired" "Domain $1 expire date is $e_d." 
    fi
}

#检测上次运行的whois查询进程是否存在
#若存在,须要杀死进程,以避免影响本次脚本执行
if pgrep whois &>/dev/null
then
    killall -9 whois
fi

is_install_whois

for d in aaa.com bbb.com  aaa.cn
do
    notify $d
done

实例 :

在输入栏里面输入”whois.chinaz.com“ ,查看某个域名的具体信息。

安装查看域名的whois命令软件包,

安装YUM以后,而后就能够安装了

查看aminglinux.com域名的具体信息。

查询百度的域名的过时时间。

只打印出过时的时间

执行脚本,查看结果

 

注意  : 

 which whois >/dev/null 2>/dev/null                         #检测whois软件包

e_d=`whois $1|grep 'Expiry Date'|awk '{print $4}'|cut -d 'T' -f 1`      #获取域名的过时的详细信息,
e_d=`whois $1|grep 'Expiration'|tail -1 |awk '{print $5}' |awk -F 'T' '{print $1}'`                                           #只打印出过时的时间

 

e_t1=$[$e_t-$n]                             #$e_t是过时时间,$n表示一周,$e_t-$n域名过时前的一周

e_t2=$[$e_t+$n]                              #   $e_t+$n域名过时后的一周

 

if [ $t1 -ge $e_t ] && [ $t1 -lt $e_t2 ]                     #当前时间大于$e_t 域名的过时时间,而且,时间小于一周

 

e_d=`whois $1|grep 'Expiration Time'|awk '{print $3}'`
    fi                                 #只打印出过时的时间

if [ $t1 -ge $e_t1 ] && [ $t1 -lt $e_t ]                 #若是当前日期不是大于等于$e_t1的过时前的一周,而且,当前日期小于一周后的时间,表示域名过时时间不到一周了。 不到一周就过时或者过时了不到一周,就发邮件。

 

 

90、题目要求   :    自动密钥认证

写一个shell脚本,当咱们执行时,提示要输入对方的ip和root密码,而后能够自动把本机的公钥增长到对方机器上,从而实现密钥认证。

【核心要点】

expect                                     #分发脚本命令

ssh-copy-id                                    #公钥

参考答案

#!/bin/bash
#这个脚本用来自动配置密钥认证
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-14

read -p "输入一个IP地址: " ip
read -p "输入此机器的root密码: " pasd

is_install()
{
    if ! rpm -q $1 &>/dev/null
    then
	yum installl -y $1
    fi
}

is_install openssh-clients
is_install expect

if [ ! -f ~/.ssh/id_rsa.pub ]
then
    echo -e "\n" |ssh-keygen  -P ''
fi

cat > key.expect <<EOF
#!/usr/bin/expect
set host [lindex \$argv 0]
set passwd [lindex \$argv 1]
spawn ssh-copy-id root@\$host
expect {
    "yes/no" { send "yes\r"; exp_continue}
    "password:" { send "\$passwd\r" }
}
expect eof
EOF

chmod a+x key.expect

./key.expect $ip $pasd

实例 :

查看机器是否安装远程登陆的命令软件包和分发脚本的命令 : openssh-clients、expect

远程登陆登陆B机器

查看本机密钥 : cat ~/.ssh/id_rsa.pub,ssh-copy-id root@1.1.1.1把本机的公钥增长到对方机器上,而后输入密码就好了。秘钥拷贝到129机器上拷贝成功,129机器上要拷贝到秘钥的目录 :~/.ssh/authorized_keys

查看本机器上的秘钥

写一个分发脚本1.expect ,使用分发脚本登陆    B机器,而后输入IP地址和密码。

查看公钥

查看秘钥存放的目录

查看生成的秘钥

执行脚本,查看结果

注意  : 

if ! rpm -q $1 &>/dev/null                      #查看命令是否运行openssh-clients、expect,若是没有,就安装。

if [ ! -f ~/.ssh/id_rsa.pub ]                           #查看本地家目录有没有秘钥id_rsa.pub,若是没有,就生成。

 

写入一个分发脚本,下面是内容

set host [lindex \$argv 0]
set passwd [lindex \$argv 1]
spawn ssh-copy-id root@\$host

 

 

来源 : https://github.com/aminglinux/shell100/blob/master/61.md

相关文章
相关标签/搜索