shell实例100例《六》

如何让系统的时间同步php

5一、题目要求  :  判断网站是否正常python

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

【核心要点】nginx

curl -l urlgit

如何截取状态吗github

参考答案

#!/bin/bash
#这个脚本用来判断一个网址是否正常
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-11-01

url="http://www.apelearn.com/index.php"
mail_user=3067986058@qq.com

code=`curl -I $url 2>/tmp/curl.err|head -1|awk '{print $2}'`
if [ -z "$code" ]
then
    python mail.py $mail_user "$url访问异常" "`cat /tmp/curl.err`"
    exit
elif [ $code != "200" ]
then
    curl -I $url &> /tmp/curl.log
    python mail.py $mail_user "$url访问异常 状态码$code" "`/tmp/curl.log`" 
fi

实例 :ajax

经过curl -I 返回的状态码来断定所访问的网站正常shell

将错误的输出重定向到/dev/null,只显示状态码api

 

脚本执行的结果bash

注意  : 

elif [ $code != "200" ]                  #当code不等于200时

if [ -z "$code" ]                        #当-z为空。

由于本脚本中没有mail.py脚本,因此错误的网址,就不能记录到/tmp/curl.err,为了使脚本正常运行,须要放一个mail.py脚本和本脚本在同一个目录下。

 

5二、题目要求  :  小于5k文件打包

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

【核心要点】

find ./ -type f  -size -5k                   #查找小于5k文件

date +%F                                #打包成当前日期为文件名前缀的压缩包

参考答案

#!/bin/bash
#这个脚本用来打包用户家目录下小于5k的文件
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-11-01

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

实例 :

查找小于5k的文件

查找小于5k的文件,使用xargs命令,全部的文件只显示在一行。

当前用户的家目录

执行脚本,查看结果

查看压缩打包的内容

注意  : 


t=`date +%F`                               #打印出当前系统时间

 

 

5三、题目要求    监控22端口是否被封

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

【核心要点】

一、如何判断是否封掉22端口是本题关键点

二、思路是查看iptables INPUT链规则,看是否有目标端口为22,的规则,而且规则target为DROP或者REJECT。有这两个,说明被封了。

参考答案

#!/bin/bash
#这个脚本用来解封22端口
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-11-01

iptables -nvL INPUT --line-numbers |grep -w 'dpt:22' |awk '$4 ~/REJECT|DROP/ {print $1}' > /tmp/iptables.log
n=`wc -l /tmp/iptables.log`

if [ $n -gt 0 ]
then
    for n in `tac /tmp/iptables.log`
    do
	iptables -D INPUT $n
    done
fi

实例 :

查看全部的iptbale链,删除规则2,命令 : “iptables -D INPUT 2”

给IPTABLES的22端口写两个规则,DROP,REJECT

iptables规则中过滤出,含有dpt:22的行

iptables规则中过滤出,含有dpt:22的行,找出第三行,含有REJECT或者DROP的行

使用line-number查找含有含有REJECT或者DROP的行

添加规则

只显示含有REJECT或者DROP的行,只打印出来行号

先删除第一个规则,而后查看只显示含有REJECT或者DROP的行,只打印出来行号。【注意: 删除的规则,应该从最底下的规则5,开始删除】

执行脚本,查看脚本运行的结果

 

注意  : 

iptables -nvL INPUT --line-numbers |grep -w 'dpt:22' |awk '$4 ~/REJECT|DROP/ {print $1}' > /tmp/iptables.log                  #iptables规则中过滤出,含有dpt:22的行,找出第四行,含有REJECT或者DROP的行

$n -gt 0                          #$n大于了,开始解封

for n in `tac /tmp/iptables.log`                #倒叙解封,/tmp/iptables.log

 

5四、题目要求   : 分析日志

已知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”
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”

【核心要点】

一、须要截取10点到12点之间的日志,思路是用grep过滤时间关键字。

二、请求的IP在日志中在第一段,用awk截取便可。

参考答案

#!/bin/bash
#这个脚本用来分析Nginx访问日志
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-11-01

export LANG=en
log="/usr/local/nginx/logs/access.log"
t=`date +%d/%b/%Y:1[01]:[0-5][0-9]:`

egrep "$t" $log|awk '{print $1}' |sort -n |uniq -c |sort -n |tail -1 |awk '{print $2}'

实例 :

执行脚本,查看脚本运行的结果

注意  : 

t=`date +%d/%b/%Y:1[01]:[0-5][0-9]:`                     #截取10,11点两个小时的日志,是时间59分59秒

egrep "$t" $log|awk '{print $1}' |sort -n |uniq -c |sort -n |tail -1 |awk '{print $2}'                                 #排序,统计行数,排序,截取第二行

 

 

5五、题目要求    打印数字

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

例:若是输入的是5,打印1 2 3 4 5,而后继续输入15,而后打印6 7 …14 15 以此类推。

【核心要点】

一、根据题目要求,首先用read -p 提示用户输入数字,获取到第一个数字。

二、此时须要判断用户输入的是纯数字。

三、第一次循环后,若用户继续输入数字,此时不只要判断输入的是是不是纯数字,还要判断输入的数字是否比第一个数字大。

参考答案

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

read -p "Please input a number: " n
n1=`echo $n |sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
    echo "Please input a number."
    exit
fi

for i in `seq 1 $n`
do
    echo $i
done

read -p "If continue? y/n" c

case $c in
  n|N)
    exit
    ;;
  y|Y)
    read -p "Please input a number: " n2
    n3=`echo $n2|sed 's/[0-9]//g'`
    if [ -n "$n3" ]
    then
	echo "Please input a number."
	exit
    fi
    if [ $n2 -le $n ]
    then
	echo "$n2 should grater than $n."
        exit
    fi
    for i in `seq $[$n+1] $n2`
    do
	echo $i
    done
    ;;
  *)
    echo "Please input y or n."
    ;;
esac

实例 :

执行脚本,查看脚本运行的结果

注意  : 

if [ -n "$n1" ]                          #第一次执行,若是$n1 不为空,提示"Please input a number.",而后退出脚本

n1=`echo $n |sed 's/[0-9]//g'`                   #清空全部的数字

 

 n3=`echo $n2|sed 's/[0-9]//g'`                   #清空全部的数字

 for i in `seq $[$n+1] $n2`                        #

for i in `seq 1 $n`                        #打印全部的数字,而后提示 “"If continue? y/n"”

if [ $n2 -le $n ]                                                    #$n2小于等于1,提示 "$n2 should grater than $n."

 

5六、题目要求 :  打印数字

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

# This is a test file.
# Test insert line into this file.

【核心要点】

一、给文档指定行后面增长内容,可使用sed搞定

二、比较笨的方法是,依次按顺序打印前5行,而后打印要增长的行,再从文本第6行开始一直到结束依次打印剩余的行。

参考答案

#!/bin/bash
#这个脚本用来给文件增长行
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-11-01

n=0
cat 1.txt |while read line
do
    n=$[$n+1]
    if [ $n -eq 5 ]
    then
        echo $line
	echo -e "# This is a test file.\n# Test insert line into this file."
    else
	echo $line
    fi
done

实例 :

写一个文档1.txt,添加内容

在文档中,第五、6行添加内容

在文档中,第5行增长两行内容,使用\n

在文档中,第5行增长两行内容,

执行脚本,查看脚本运行的结果

注意  : 

n=0                       #n是计数器

line                          #line  是变量

  if [ $n -eq 5 ]                      #等于第五行

echo $line                                   #第一个echo $line,是打印第5行的意思

 


5七、题目要求 :  备份etc目录

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

【核心要点】

一、yymmdd用date +%y%m%d表示

二、每个月第一天,须要判断date +%d是不是01

参考答案

#!/bin/bash
#这个脚本用来备份/etc/目录
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-02

d1=`date +%d`
d2=`date +%y%m%d`

if [ $d1 == "01" ]
then
    cd /etc/
    tar czf /root/bak/$d2_etc.tar.gz ./
fi

实例 :

date +%d是不是01,大写的Y,表示显示4位数。

执行脚本,查看脚本运行的结果

注意  : 


if [ $d1 == "01" ]                                    #若是是01,执行下面的指令

   tar czf /root/bak/$d2_etc.tar.gz ./                 #打包到 /root/bak/$d2_etc.tar.gz,

 

5八、题目要求  :  找出重复的单词

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

【核心要点】

把非英文的字符删除掉(用空格替换),剩下的就是英文字母或者单词。 

参考答案

#!/bin/bash
#这个脚本用来找出重复的单词
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-02

for w in `sed 's/[^a-zA-Z]/ /g' $1`
do
    echo $w
done |sort |uniq -c |sort -nr|head

实例 :

/etc/passwd文件在中将全部非英文字母,替换成空格、全局

/etc/passwd文件在中将全部非英文字母,替换成空格、全局,显示在一列。

查看前10列

执行脚本,查看脚本运行的结果

注意  : 

 done |sort |uniq -c |sort -nr|head                            #排序,统计行数,排序,查看前10列

 

5九、题目要求   :  人员分组

需求是,把全部的成员平均分红若干个小组。这里,提供一我的员列表,好比成员有50人,须要分红7个小组,要求随机性,每次和每次分组的结果应该不一致。

【核心要点】

一、首先肯定好要分的小组个数,本题中假设有50人,分7个小组,平均每一个小组个数应为7。

二、为了实现随机性,咱们能够根据人名的长度来作一个运算,好比用一个随机数+人名的长度获得一个随机数,而后除以7取余数,余数是几就把该用户分到第几组里。

三、考虑到人员数量较少,最终分组结果必定不均衡,好比,有的小组分了10我的,但有的小组却分到了3我的,这样严重不均衡。

四、为了让人员更加均衡,须要把人数偏多的组(大于7的)均分一部分红员到人数偏少的组(小于7的)。

参考人员名单

xiaoguisheng
guoyuqing
xiongyongzheng
mengjintang
chaizuzhou
zhousheng
xufangming
zhaoliangyun
hanshiru
wangxianyi
zhangjipei
luxiuli
yangshugen
guoyongzhi
lijianguo
wuqiongchen
dinglin
yaoyashan
yinzijia
wangbencheng
liuxiuwen
chenzuqi
leyuguo
baozongyao
fenghao
sunxiaoquan
zhangyaxian
lijiuzhe
dulichun
lixi
shenpeiwen
zousilin
luoping
chaiyan
fandaozhang
huzixiang
jinzhen
zhujunfeng
liqianbiao
hangyanliang
luorenjian
loujianji
fujianzhou
gengyiwu
jinjigui
liuzhizhong
lisanyan
lisili
zhangyiyu
songguozhen
zhangxinghua
zhaozhiyong
huanghe
xiaojie
fanhongfei
wangguiwen
renshumin
songfuying
zhanghaibo
liguangqun
puaihua
yanzhihua
gaojixian
liulai
funing
chenruizhi
chendaxin
laishaoying
xujian
xiaozhekou
xuxiaping
jiangchunqing

参考答案

【核心要点】

#!/bin/bash
#这个脚本用来给人员分组
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-02

#人员列表文件
f=member.txt
#小组数
group_n=7
#人员总数
member_n=`wc -l $f|awk '{print $1}'`

#根据姓名计算该用户所在小组的id
get_n()
{
    #根据姓名计算cksum值
    l=`echo $1|cksum|awk '{print $1}'`
    #获取一个随机数
    n1=$RANDOM
    #cksum值和随机数相加,而后除以小组数取余,这样能够确保每次获取到的余数都不同
    n2=$[$n1+$l]
    g_id=$[$n2%$group_n]
    #假如小组数为7,则余数范围0-6,若是余数为0,则小组为7
    if [ $g_id -eq 0 ]
    then
        g_id=$group_n
    fi
    echo $g_id
}

for i in `seq 1 $group_n`
do
    #n_$i.txt为临时文件,用来记录该小组内的成员
    #脚本以前执行过,则该文件会存在,本次执行脚本前应该删除掉这个临时文件
    [ -f n_$i.txt ] && rm -f n_$i.txt
done


shuf $f|while read name
do
    #计算用户所在小组的id
    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 $group_n|shuf`
    do
        n=`nu n_$i.txt`
        if [ $n -gt $ma ]
        then
            ma=$n
       fi
    done
    echo $ma
}

#获取组员人数最少的小组
min(){
    mi=$member_n
    for i in `seq 1 $group_n|shuf`
    do
       n=`nu n_$i.txt`
       if [ $n -lt $mi ]
       then
           mi=$n
       fi
    done
    echo $mi
}

#定义四舍五入函数
div()
{
    n=`echo "scale=1;$1/$2"|bc`
    n1=`echo "scale=1;$n+0.5"|bc`
    echo $n1|cut -d. -f1
}

#小组组员平均值(非四舍五入)
ava_n=$[$member_n/$group_n]
#小组组员平均值(四舍五入)
ava_n1=`div $member_n $group_n`

if [ $ava_n -eq $ava_n1 ]
then
    #定义初始最小值
    ini_min=1
    #如下while循环要作的事情,就是要把人数多的组里的人搞到人数少的组里去
    #此while循环的条件是,当人数最少的组成员数小于组员平均值
    while [ $ini_min -lt $ava_n1 ]
    do
        #找出人数最多的组
        m1=`max`
        #找出人数最少的组
        m2=`min`
        for i in `seq 1 $group_n|shuf`
        do
            n=`nu n_$i.txt`
            #找到人数最多的组对应的文件f1(可能有多个,这里取出现的第一个便可)
            if [ $n -eq $m1 ]
            then
                f1=n_$i.txt
            #找到人数最少的组对应的文件f2(可能有多个,这里取出现的第一个便可)
            elif [ $n -eq $m2 ]
            then
                f2=n_$i.txt
            fi
        done
        #取f1中最后一我的名
        name=`tail -n1 $f1`
        #将这我的名追加写入f2中
        echo $name >> $f2
        #在f1中删除刚刚取走的人名
        sed -i "/$name/d" $f1
        #把此时的最少组人员数赋值给ini_min
        ini_min=`min`
    done
else
    #定义初始最大值
    ini_max=$member_n
    while [ $ini_max -gt $ava_n1 ]
    do
        #找出人数最多的组
        m1=`max`
        #找出人数最少的组
        m2=`min`
        for i in `seq 1 $group_n|shuf`
        do
            n=`nu n_$i.txt`
            #找到人数最多的组对应的文件f1(可能有多个,这里取出现的第一个便可)
            if [ $n -eq $m1 ]
            then
                f1=n_$i.txt
                #找到人数最少的组对应的文件f2(可能有多个,这里取出现的第一个便可)
            elif [ $n -eq $m2 ]
            then
                f2=n_$i.txt
            fi
        done
        #取f1中最后一我的名
        name=`tail -n1 $f1`
        #将这我的名追加写入f2中
        echo $name >> $f2
        #在f1中删除刚刚取走的人名
        sed -i "/$name/d" $f1
        #把此时的最少组人员数赋值给ini_min
        ini_max=`max`
    done
fi

for i in `seq 1 $group_n`
do
    echo -e "\033[34m$i 组成员有:\033[0m"
    cat n_$i.txt
    #把临时文件删除
    rm -f n_$i.txt
    echo
done

实例 :

执行脚本,查看脚本运行的结果

注意  : 

要bc命令,bc是一个计算器,须要使用:yum install -y bc

member_n=`wc -l $f|awk '{print $1}'`                               #统计人员总数和行数

shuf $f|while read name                                    #将小组人员,随机分配。

echo -e "\033[34m$i 组成员有:\033[0m"                                #

 

 

60、题目要求   :   比较两个数大小

写一个shell脚本,比较两个数的大小,支持浮点数,两个数经过shell参数的形式提供。

【核心要点】

参考答案

#!/bin/bash
#这个脚本用来比较两个数大小
#做者:猿课-阿铭 www.apelearn.com
#日期:2018-12-05

if [ $# -ne 2 ]
then
    echo "请提供两个参数."
    exit
fi

if_number() 
{
    if echo $1|grep -q '^-'
    then
	nu=`echo $1|sed 's/^-//'`
    else
	nu=$1
    fi
    n=`echo $nu|sed 's/[0-9.]//g'`
    if [ -n "$n" ]
    then
	echo "$1不是合法数字."
	exit
    fi
    if echo $1|grep -q '^\.'
    then
	echo "$1不是合法数字."
	exit
    fi
}

if_number $1
if_number $2

n1=`echo "$1>$2"|bc`
if [ $n1 -eq 1 ]
then
    echo "$1 > $2"
else
    if [ "$1" == "$2" ]
    then
	echo "$1 = $2"
    else
	echo "$1 < $2"
    fi
fi

实例 :

执行脚本,查看脚本运行的结果

注意  : 

 

写一个脚本,add_title.sh,写入前缀,而后执行:sh add_title.sh 12.sh,将前缀写入12脚本中

执行结果

 

 

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

相关文章
相关标签/搜索