shell脚本实例(五)

【脚本59】判断日期是否合法

用shell脚本判断输入的日期是否合法。就是判断日期是都是真实的日期,比如20170110就是合法日期,20171332就不合法

  • 参考代码:
#!/bin/bash

#check date

if [ $# -ne 1 ] || [ ${#1} -ne 8 ]
then
    echo "Usage: bash $0 yyyymmdd"
    exit 1
fi

datem=$1
year=${datem:0:4}
month=${datem:4:2}
day=${datem:6:2}

if echo $day|grep -q '^0'
then
    day=`echo $day |sed 's/^0//'`
fi

if cal $month $year >/dev/null 2>/dev/null
then
    daym=`cal $month $year|egrep -v "$year|Su"|grep -w "$day"`
    if [ "$daym" != "" ]
    then
        echo ok
    else
        echo "Error: Please input a wright date."
    exit 1
    fi
else
    echo "Error: Please input a wright date."
    exit 1
fi

【脚本60】监控网卡

  1. 每10分钟检测一次指定网卡的流量
  2. 如果流量为0,则重启网卡
  • 参考代码:
#!/bin/bash

LANG=en
n1=`sar -n DEV 1 60 |grep eth0 |grep -i average|awk '{print $5}'|sed 's/\.//g'`
n2=`sar -n DEV 1 60 |grep eth0 |grep -i average|awk '{print $6}'|sed 's/\.//g'`
if [ $n1 == "000" ] && [ $n2 == "000" ]
then
    ifdown eth0
    ifup eth0
fi

然后写个cron,10分钟执行一次

【脚本61】监控web可用性

写一个shell脚本,通过curl -I 返回的状态码来判定所访问的网站是否正常。比如,当状态码为200时,才算正常。

  • 参考代码:
#/bin/bash

url="http://www.apelearn.com/index.php"
sta=`curl -I $url 2>/dev/null |head -1 |awk '{print $2}'`

if [ $sta != "200" ]
then
    python /usr/local/sbin/mail.py xxx@qq.com "$url down." "$url down"
fi

【脚本62】文件打包

  • 需求:
    将用户家目录(考虑到执行脚本的用户可能是普通用户也可能是root)下面小于5KB的文件打包成tar.gz的压缩包,并以当前日期为文件名前缀,例如今天打包的文件为2017-09-15.tar.gz。

  • 参考代码:

#!/bin/bash

t=`date +%F`
cd $HOME
tar czf $t.tar.gz `find . -type f -size -5k`

【脚本63】端口解封

一个小伙伴提到一个问题,他不小心用iptables规则把sshd端口22给封掉了,结果不能远程登陆,要想解决这问题,还要去机房,登陆真机去删除这规则。 问题来了,要写个监控脚本,监控iptables规则是否封掉了22端口,如果封掉了,给打开。 写好脚本,放到任务计划里,每分钟执行一次。

  • 参考代码:
#!/bin/bash
# check sshd port drop

/sbin/iptables -nvL --line-number|grep "dpt:22"|awk -F ' ' '{print $4}' > /tmp/drop.txt
i=`cat /tmp/drop.txt|head -n 1|egrep -iE "DROP|REJECT"|wc -l`
if [ $i -gt 0 ]
then
    /sbin/iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT
fi

【脚本64】统计分析日志

已知nginx访问的日志文件在/usr/local/nginx/logs/access.log内

请统计下早上10点到12点 来访ip最多的是哪个?

  • 日志样例:
111.199.186.68 – [15/Sep/2017:09:58:37 +0800]  “//plugin.php?id=security:job” 200 “POST //plugin.php?id=security:job HTTP/1.1″”http://a.lishiming.net/forum.php?mod=viewthread&tid=11338&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline” “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3141.7 Safari/537.36” “0.516”

203.208.60.208 – [15/Sep/2017:09:58:46 +0800] “/misc.php?mod=patch&action=ipnotice&_r=0.05560809863330207&inajax=1&ajaxtarget=ip_notice” 200 “GET /misc.php?mod=patch&action=ipnotice&_r=0.05560809863330207&inajax=1&ajaxtarget=ip_notice HTTP/1.1″”http://a.lishiming.net/forum.php?mod=forumdisplay&fid=65&filter=author&orderby=dateline” “Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3141.7 Safari/537.36” “0.065”

实现这个需求使用如下命令即可:

grep '15/Sep/2017:1[0-2]:[0-5][0-9]:' /usr/local/nginx/logs/access.log|awk '{print $1}'|sort -n|uniq -c |sort -n|tail -n1

【脚本65】打印数字

写一个shell脚本。提示你输入一个暂停的数字,然后从1打印到该数字。然后询问是否继续。继续的话在输入个在数字 接着打印。不继续退出。

  • 例:
    如果输入的是5,打印1 2 3 4 5 然后继续 输入15 然后打印 6 7 …14 15 依此类推。

  • 参考代码:

#!/bin/bash

read -p "请输入您想要暂停的数字:" number_1

for i in `seq 1 $number_1`;
do
        echo $i
done

read -p "是否继续输入数字?" a
if [ $a == "yes" ];then
        read -p "请继续输入您想要暂停的数字:" number_2
        number_3=$[$number_1+1]
        if [ $number_2 -gt $number_1 ];then
                for h in `seq $number_3 $number_2`;
                do
                        echo $h
                done
        else
                echo "输入数字错误,请输入大于的数字!"
        fi
else
        exit
fi

【脚本66】给文档增加内容

在文本文档1.txt第5行(假设文件行数大于5)后面增加如下内容:

# This is a test file.

# Test insert line into this file.
  • 参考命令:
sed -i "5a # This is a test file.\n# Test insert line into this file." 1.txt

【脚本67】备份etc下面文件

设计一个shell程序,在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名为如下形式”yymmdd_etc.tar.gz”,yy为年,mm为月,dd为日。

  • 参考代码:
#!/bin/sh 

if [ ! -d /root/bak ]
then
    mkdir /root/bak
fi
prefix=`date +%y%m%d`
d=`date +%d`
if [ $d == "01" ]
then
    cd /etc/
    tar czf  /root/bak/$prefix_etc.tar.gz ./
fi

【脚本68】计算单词重复次数

将文件内所有的单词的重复次数计算出来,只需要列出重复次数最多的10个单词。

假设文档名字叫做a.txt,使用如下命令即可:

sed 's/[^a-zA-Z]/ /g' a.txt|xargs -n1 |sort |uniq -c |sort -nr |head

【脚本69】成员分组

  • 需求
    把所有的成员平均得分成若干个小组。这里,我会提供一个人员列表,比如成员有50人,需要分成7个小组,要求随机性,每次和每次分组的结构应该不一致。

假设成员列表文件为members.txt

  • 参考代码:
#!/bin/bash
f=members.txt
n=`wc -l $f|awk '{print $1}'`
get_n()

{
    l=`echo $1|wc -c`
    n1=$RANDOM
    n2=$[$n1+$l]
    g_id=$[$n1%7]
    if [ $g_id -eq 0 ]
    then
        g_id=7
    fi
    echo $g_id
}

for i in `seq 1 7`
do
    [ -f n_$i.txt ] && rm -f n_$i.txt
done
for i in `seq 1 $n`
do
    name=`sed -n "$i"p $f`
    g=`get_n $name`
    echo $name >> n_$g.txt
done

nu(){
    wc -l $1|awk '{print $1}'
}

max(){
    ma=0
    for i in `seq 1 7`
    do
        n=`nu n_$i.txt`
        if [ $n -gt $ma ]
        then
            ma=$n
       fi
    done
    echo $ma
}

min(){
    mi=50
    for i in `seq 1 7`
    do
       n=`nu n_$i.txt`
       if [ $n -lt $mi ]
       then
           mi=$n
       fi
    done
    echo $mi
}

ini_min=1
while [ $ini_min -le 7 ]
do
    m1=`max`
    m2=`min`
    ini_min=m2
    for i in `seq 1 7`
    do
        n=`nu n_$i.txt`
        if [ $n -eq $m1 ]
        then
           f1=n_$i.txt
        elif [ $n -eq $m2 ]
        then
          f2=n_$i.txt
        fi
    done
    name=`tail -n1 $f1`
    echo $name >> $f2
    sed -i "/$name/d" $f1
    ini_min=$[$ini_min+1]
done

for i in `seq 1 7`
do
    echo "$i 组成员有:"
    cat n_$i.txt
    echo
done

【脚本70】shell中的小数

有一组式子如下:
a=0.5
b=3
c=a*b
求c的值

  • 参考代码:
#!/bin/bash
a=0.5
b=3
c=`echo "scale=1;$a*$b"|bc`
echo $c

【脚本71】a.txt有b.txt没有

有两个文件a.txt和b.txt,需求是,把a.txt中有的并且b.txt中没有的行找出来,并写入到c.txt,然后计算c.txt文件的行数。

  • 参考代码:
#!/bin/bash

n=`wc -l a.txt|awk '{print $1}'`
[ -f c.txt ] && rm -f c.txt
for i in `seq 1 $n`
do
    l=`sed -n "$i"p a.txt`
    if ! grep -q "^$l$" b.txt
    then
    echo $l >>c.txt
    fi
done
wc -l c.txt

或者用grep实现

grep -vwf b.txt a.txt > c.txt; wc -l c.txt

【脚本72】杀死进程

把当前用户下所有进程名字中含有”java”的进程关闭。

  • 参考答案:
ps -u $USER |awk '$NF ~ /java/ {print $1}'|xargs kill

【脚本73】备份数据表

用shell实现,以并发进程的形式将mysql数据库所有的表备份到当前目录,并把所有的表压缩到一个压缩包文件里。

假设数据库名字为mydb,用户名为zero,密码为passwd。

  • 提示:
    在shell中加上&可以将命令丢到后台,从而可以同时执行多条命令达到并发的效果。

  • 参考代码:

#!/bin/bash
pre=`date +%F` 
for d in `mysql -uaming -ppasswd mydb -e "show tables"|grep -v 'Tables_in_'`
do
    mysqldump -uaming -ppasswd mydb $d > $d.sql &
done
tar czf $pre.tar.gz *.sql 
rm -f *.sql

【脚本74】监控节点

一个网站,使用了cdn,全国各地有几十个节点。需要你写一个shell脚本来监控各个节点是否正常。

  • 假如:

监控的url为www.xxx.com/index.php
源站ip为88.88.88.88

  • 参考代码:
#!/bin/bash

url="www.xxx.com/index.php"
s_ip="88.88.88.88"
curl -x $s_ip:80 $url > /tmp/source.html 2>/dev/null

for ip in `cat /tmp/ip.txt`
do
    curl -x $ip:80 $url 2>/dev/null >/tmp/$ip.html
    [ -f /tmp/$ip.diff ] && rm -f /tmp/$ip.diff
    touch /tmp/$ip.diff
    diff /tmp/source.html /tmp/$ip.html > /tmp/$ip.diff 2>/dev/null
    n=`wc -l /tmp/$ip.diff|awk '{print $1}'`
    if [ $n -lt 0 ]
    then
        echo "node $ip sth wrong."
    fi
done

【脚本75】破解字符串

已知下面的字符串是通过RANDOM随机数变量md5sum|cut-c 1-8截取后的结果,请破解这些字符串对应的md5sum前的RANDOM对应数字?

21029299
00205d1c
a3da1677
1f6d12dd
890684ba

-解题思路:
通过每次传递一个参数的方式,来实现依次破解,$RANDOM的范围为0-32767。

  • 参考代码:
#!/bin/bash

for n in {0..32767}
do
        MD5=`echo $n | md5sum | cut -c 1-8`
        if [ "$MD5" == "$1" ];then
            echo "$n $1 "
            break
        fi
done

【脚本76】判断cpu厂商

  • 写一个脚本:

判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。
如果其生产商为AuthenticAMD,就显示其为AMD公司;
如果其生产商为GenuineIntel,就显示其为Intel公司;
否则,就说其为非主流公司。

  • 参考代码:
#!/bin/bash

m=`cat /proc/cpuinfo |grep vendor_id|awk  -F":" '{print $2}'|tail -1`
if [ $m == "GenuineIntel" ]
then
     echo "cpu is 英特尔"
elif [ $m == "AuthenticAMD" ]
then
     echo "cpu is AMD"
else
     echo "cpu is 非主流"
fi

   转载规则


《shell脚本实例(五)》 helen 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录