Shell案例

Posted 帮小熊梳毛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell案例相关的知识,希望对你有一定的参考价值。

 

案例一

1、问题:

请按照这样的日期格式(xxxx-xx-xx)每日生成一个文件,

2、分析:

#! /bin/bash

d=`date +%F`

logfile=$d.log

df -h > $logfile

 

3、流程图:

 

4、实现:

 

#!/bin/bash

d=`date +%F`

dir=/data/logs/disklog

if [ ! -d $dir ]

then

    mkdir -p $dir

fi

df -h > $dir/$d.log

find $dir/ -mtime +365 |xargs rm

 

 

 

案例二

 

 

 

 

1、问题:

有日志1.log,部分内容如下

```

112.111.12.248 – [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com “/seccode.php?update=0.5593110133088248″ 200″http://formula-x.haotui.com/registerbbs.php” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)”

61.147.76.51 – [25/Sep/2013:16:08:31 +0800]xyzdiy.5d6d.com “/attachment.php?aid=4554&k=9ce51e2c376bc861603c7689d97c04a1&t=1334564048&fid=9&sid=zgohwYoLZq2qPW233ZIRsJiUeu22XqE8f49jY9mouRSoE71″ 301″http://xyzdiy.5d6d.com/thread-1435-1-23.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)”

```

统计出每个IP访问量有多少

2、分析:

awk、sort、uniq命令

3、流程图:

 

 

4、实现:

awk \'{print $1}\' 1.log|sort |uniq -c |sort -n -r

 

 

案例三

 

 

1、问题:

 

写一个脚本计算一下linux系统所有进程占用内存大小的和。

2、分析:

 

* ps命令用法

* for循环

* 加法运算

3、流程图:

 

 

4、实现:

```shell

#!/bin/bash

sum=0

for n in `ps aux |grep -v \'TIME COMMAND\'|awk \'{print $6}\'`

do

    sum=$[$sum+$n]

done

echo $sum

 

5、实现解析:

 

6、结果验证

 

 

案例

 

 

 

 

 

1、问题:

设计一个脚本,监控远程的一台机器(假设ip为180.163.26.39)的存活状态,当发现宕机时发一封邮件给你自己。

2、分析:

ping -c10 180.163.26.39 通过ping来判定对方是否在线

 

 发邮件脚本 https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D22Z/mail.py

3、流程图:

 

 

4、实现:

 

#!/bin/bash

n=`ping -c5 180.163.26.39|grep \'packet\' |awk -F \'%\' \'{print $1}\' |awk \'{print $NF}\'`

if [ -z "$n" ]

then

    echo "脚本有问题。"

    python mail.py  $m "检测机器存活脚本$0有问题" "获取变量的值为空"

    exit

else

    n1=`echo $n|sed \'s/[0-9]//g\'`

    if [ -n "$n" ]

    then

        echo "脚本有问题。"

        python mail.py  $m "检测机器存活脚本$0有问题" "获取变量的值不是纯数字"

        exit

    fi

fi

 

if

m=123@qq.com

while :

do

    if [ $n -ge 50 ]

    then

           python mail.py $m "机器宕机" "丢包率是$n%"

    fi

    sleep 30

done

5、实现解析:

 

6、结果验证

 

案例五

 

 

1、问题:

写一个shell脚本,检测所有磁盘分区使用率和inode使用率并记录到以当天日期为命名的日志文件里,当发现某个分区容量或者inode使用量大于85%时,发邮件通知你自己。

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

dir=/tmp/disk

d=`date +%F`

mail=123@123.com

 

[ -d $dir ] || mkdir $dir

 

df >> $dir/$d.log

df -i >> $dir/$d.log

 

df|sed \'1d\' |awk -F \' +|%\' \'$5>=85 {print $7}\' > $dir/df.tmp

df -i|sed \'1d\' |awk -F \' +|%\' \'$5>=85 {print $7}\' > $dir/df_i.tmp

 

n1=`wc -l $dir/df.tmp|awk \'{print $1}\'`

n2=`wc -l $dir/df_i.tmp|awk \'{print $1}\'`

 

tag=0

if [ $n1 -gt 0 ]

then

    if [ $n2 -gt 0 ]

    then

       tag=11

    else

       tag=10

    fi

else

    if [ $n2 -gt 0 ]

    then

       tag=01

    else

       tag=00

    fi

fi

 

case $tag in

    11)

       python mail.py $mail "磁盘空间和inode使用率高于85%" "`cat $dir/df.tmp $dir/df_i.tmp|xargs`"

        ;;

    10)

       python mail.py $mail "磁盘空间使用率高于85%" "`cat $dir/df.tmp|xargs`"

       ;;

    01)

       python mail.py $mail "磁盘inode使用率高于85%" "`cat $dir/df_i.tmp|xargs`"

       ;;

    *)

       ;;

esac

 

5、实现解析:

 

6、结果验证

 

案例六

 

 

 

1、问题:

有一台服务器作为web应用,有一个目录(/data/web/attachment)不定时地会被用户上传新的文件,但是不知道什么时候会上传。所以,需要我们每5分钟做一次检测是否有新文件生成。

 

请写一个shell脚本去完成检测。检测完成后若是有新文件,还需要将新文件的列表输出到一个按年、月、日、时、分为名字的日志里。

 

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

basedir=/data/web/attachment

t=`date +%Y%m%d%H%M`

 

find $basedir/ -type f -mmin -5 > /tmp/file.list

n=`wc -l /tmp/file.list|awk \'{print $1}\'`

if [ $n -lt 0 ]

then

   mv /tmp/file.list /tmp/$t.list

fi

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

写一个shell脚本来看看你使用最多的命令是哪些,列出你最常用的命令top10。

2、分析:

 

3、流程图:

 

 

4、实现:

```

cat ~/.bash_history |sort |uniq -c |sort -nr |head

```

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

假如需要每小时都去执行一个脚本。在脚本中实现这样的功能,当时间是0点和12点时,需要将目录/data/log/下的文件全部清空,

 

注意只能清空文件内容而不能删除文件。而其他时间只需要统计一下每个文件的大小,一个文件一行,输出到一个按日期和时间为名字的日志里。

 

需要考虑/data/log/目录下的二级、三级、…  等子目录里面的文件。

2、分析:

 

3、流程图:

 

 

4、实现:

```

#!/bin/bash

dir=/tmp/log_stat

t=`date +%d%H`

t1=`date +%H`

logdir=/data/log

 

[ -d $dir ] || mkdir $dir

[ -f $dir/$t.log ] && rm -f $dir/$t.log

 

if [ $t == "00" -o $t == "12" ]

then

    for f in `find $logdir/ -type f`

    do

       > $f

    done

else

    for f in `find $logdir/ -type f`

    do

       du -sh $f >> $dir/$t.log

    done

fi

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

计算文档a.txt中每一行中出现的数字个数并且要计算一下整个文档中一共出现了几个数字。例如a.txt内容如下:

12aa*lkjskdj

alskdflkskdjflkjj

我们脚本名字为 ncount.sh, 运行它时:

bash ncount.sh a.txt

输出结果应该为:

2

0

sum:2

2、分析:

 

3、流程图:

 

 

4、实现:

 

 

5、实现解析:

 

6、结果验证

 

 

 

 

1、问题:

 

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

sum=0

while read line

do

    line_n=`echo $line|sed \'s/[^0-9]//g\'|wc -L`

    echo $line_n

    sum=$[$sum+$line_n]

done < $1

echo "sum:$sum"

 

```

 

5、实现解析:

 

6、结果验证

 

 

 

 

1、问题:

假如需要每小时都去执行一个脚本。在脚本中实现这样的功能,当时间是0点和12点时,需要将目录/data/log/下的文件全部清空,

 

注意只能清空文件内容而不能删除文件。而其他时间只需要统计一下每个文件的大小,一个文件一行,输出到一个按日期和时间为名字的日志里。

 

需要考虑/data/log/目录下的二级、三级、…  等子目录里面的文件。

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

dir=/tmp/log_stat

t=`date +%d%H`

t1=`date +%H`

logdir=/data/log

 

[ -d $dir ] || mkdir $dir

[ -f $dir/$t.log ] && rm -f $dir/$t.log

 

if [ $t == "00" -o $t == "12" ]

then

    for f in `find $logdir/ -type f`

    do

       > $f

    done

else

    for f in `find $logdir/ -type f`

    do

       du -sh $f >> $dir/$t.log

    done

fi

 

5、实现解析:

 

6、结果验证

 

 

1、问题:

有两台Linux服务器A和B,假如A可以直接ssh到B,不用输入密码。A和B都有一个目录叫做/data/web/ 这下面有很多文件,

 

当然我们不知道具体有几层子目录,假若之前A和B上该目录下的文件都是一模一样的。

 

但现在不确定是否一致了。固需要我们写一个脚本实现这样的功能,检测A机器和B机器/data/web/目录下文件的异同,我们以A机器上的文件作为标准。

 

比如,假若B机器少了一个a.txt文件,那我们应该能够检测出来,或者B机器上的b.txt文件有过改动,我们也应该能够检测出来(B机器上多了文件不用考虑)。

2、分析:

 

3、流程图:

 

 

4、实现:

 

#!/bin/bash

dir=/data/web

[ -f /tmp/md5.list ] && rm -f /tmp/md5.list

find $dir/ -type f > /tmp/file.list

while read line

do

    md5sum $line  >> /tmp/md5.list

done < /tmp/file.list

 

scp /tmp/md5.list B:/tmp/

[ -f /tmp/check_md5.sh ] && rm -f /tmp/check_md5.sh

 

cat >/tmp/check_md5.sh << EOF

#!/bin/bash

dir=/data/web

n=\\`wc -l /tmp/md5.list|awk \'{print \\$1}\'\\`

for i in \\`seq 1 \\$n\\`

do

    file_name=\\`sed -n "\\$i"p /tmp/md5.list |awk \'{print \\$1}\'\\`

    md5=\\`sed -n "\\$i"p /tmp/md5.list|awk \'{print \\$2}\'\\`

    if [ -f \\$file_name ]

    then

       md5_b=\\`md5sum \\$file_name\\`

       if [\\$md5_b != \\$md5 ]

       then

           echo "\\$file_name changed."

       fi

    else

       echo "\\$file_name lose."

    fi

done

EOF

scp /tmp/check_md5.sh B:/tmp/

ssh B "/bin/bash /tmp/check_md5.sh"

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

一台机器负载高,top查看有很多sh的进程,然后top -c查看可以看到对应的进程命令是sh -c /bin/clearnen.sh 。

 

经分析后发现是因为该脚本执行时间太长,导致后续执行时,上次的脚本还未执行结束。写一个脚本批量杀死所有sh的进程。

2、分析:

 

3、流程图:

 

 

4、实现:

 

#!/bin/bash

for pid in `ps aux |grep clearnen.sh |awk \'{print $2}\'`

do

    echo $pid

    kill -9 $pid

done

```

5、实现解析:

 

6、结果验证

 

 

 

 

1、问题:

写一个脚本判断你的Linux服务器里是否开启web服务?(监听80端口)如果开启了,请判断出跑的是什么服务,是httpd呢还是nginx又或者是其他的什么?

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

n=`netstat -lntp |grep \':80 \'|wc -l`

if [ $n -eq 0 ]

then

    echo "It not listen port 80"

else

    ser=`netstat -lntp |grep \':80 \'|awk -F \'/\' \'{print $NF}\'|sed \'s/ //g\'`

    echo "It is listenning port 80, and the service is $ser."

fi

 

```

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

假设,当前mysql服务的root密码为123456,写脚本检测MySQL服务是否正常(比如,可以正常进入mysql执行show processlist),

 

并检测一下当前的MySQL服务是主还是从,如果是从,请判断它的主从服务是否异常。如果是主,则不需要做什么。

2、分析:

 

3、流程图:

 

4、实现:

#!/bin/bash

mysql="/usr/local/mysql/bin/mysql -uroot -p123456"

if ! $mysql -e "show processlist" >/dev/null 2>/dev/null

then

    echo "MySQL service is down."

    exit

else

    $mysql -e "show slave status\\G" 2>/dev/null >/tmp/slave.stat

    n=`wc -l /tmp/slave.stat|awk \'{print $1}\'`

    if [ $n -eq 0 ]

    then

       echo "This is master."

    else

       echo "This is slave."

       egrep \'Slave_IO_Running:|Slave_SQL_Running:\'/tmp/slave.stat|awk -F \': \' \'{print $2}\' > /tmp/SQL.tmp

       if grep -qw "No" /tmp/SQL.tmp

       then

           echo "The slave is down."

       fi

    fi

fi

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

写一个支持选项的增加或删除用户的shell脚本,具体要求如下:

1. 只支持三个选项:\'--del\',\'--add\',\'--help\',输入其他选项报错。

2. 使用\'--add\'时,需要验证用户名是否存在,存在则反馈存在,且不添加。 不存在则创建该用户,需要设置与该用户名相同的密码。

3. 使用\'--del\'时,需要验证用户名是否存在,存在则删除用户及其家目录。不存在则反馈该用户不存在。 

4. --help选项反馈出使用方法。

5. 能用echo $?检测脚本执行情况,成功删除或添加用户为0,不成功为非0正整数。

6. 能以英文逗号分割,一次性添加或者删除多个用户。例如 adddel.sh --add user1,user2,user3

2、分析:

 

3、流程图:

 

 

4、实现:

 

#!/bin/baash

if [ $# -eq 0 ] || [ $# -gt 2 ]

then

    echo "Wrong, use bash $0 --add username, or bash $0 --del username or bash $0 --help"

    exit

fi

 

ex_user()

{

    if ! id $1 2>/dev/null >/dev/null

    then

       useradd $1 && echo "$1 add successful."

    else

       echo $1 exist.

    fi

}

 

notex_user()

{

    if id $1 2>/dev/null >/dev/null

    then

       userdel $1 && echo "$1 delete successful."

    else

       echo $1 not exist.

    fi

}

5、实现解析:

 

6、结果验证

 

 

 

 

1、问题:

写一个脚本: 计算100以内所有能被3整除的正整数的和

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

sum=0

for i in `seq 1 100`

do

    j=$[$i%3]

    if [ $j -eq 0 ]

    then

       sum=$[$sum+$i]

    fi

done

echo $sum

 

```

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

使用传参的方法写个脚本,实现加减乘除的功能。

例如:  sh  a.sh  1   2,这样会分别计算加、减、乘、除的结果。

 

要求:

1. 脚本需判断提供的两个数字必须为整数

2. 当做减法或者除法时,需要判断哪个数字大,减法时需要用大的数字减小的数字,除法时需要用大的数字除以小的数字,并且结果需要保留两个小数点。

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

is_nu()

{

    n=`echo $1 |sed \'s/[0-9]//g\'`

    if [ -n "$n" ]

    then

       echo "给出的参数必须是正整数"

        exit

    fi

}

if [ $# -ne 2 ]

then

    echo "必须要输入两个参数"

    exit

else

    is_nu $1

    is_nu $2

fi

 

big()

{

    if [ $1 -gt $2 ]

    then

       echo $1

    else

       echo $2

    fi

}

 

small()

{

    if [ $1 -lt $2 ]

    then

        echo $1

    else

        echo $2

    fi

}

 

add()

{

    sum=$[$1+$2]

    echo "$1+$2=$sum"

}

 

jian()

{

   b=`big $1 $2`

   s=`small $1 $2`

   cha=$[$b-$s]

   echo "$b-$s=$cha"

}

 

cheng()

{

    ji=$[$1*$2]

    echo "$1x$2=$ji"

}

chu()

{

   b=`big $1 $2`

   s=`small $1 $2`

   v=`echo "scale=2;$b/$s"|bc`

   echo "$b/$s=$v"

}

 

add $1 $2

jian $1 $2

cheng $1 $2

chu $1 $2

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

写一个shell脚本,实现简单的弹出式菜单功能,用户能根据显示的菜单项从键盘选择执行对应的命令。

2、分析:

#!/bin/bash

PS3="Please input your choice(1-4): "

select i in w ls pwd quit

do

    case $i in

       w)

           w

           ;;

       ls)

           ls

           ;;

       pwd)

           pwd

           ;;

       quit)

           exit

           ;;

       *)

           echo "Please input 1-3."

           ;;

    esac

done

3、流程图:

 

4、实现:

#!/bin/bash

echo -e "1) w\\n2) ls\\n3) pwd\\n4) quit"

while :

do

read -p "Please input your choice(1-4): " c

case $c in

    1)

       w

       ;;

    2)

       ls

       ;;

    3)

       pwd

       ;;

    4)

       exit

       ;;

    *)

       echo "Please input 1-4."

       ;;

esac

done

 

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

写一个shell脚本,执行中每隔5分钟检查指定的用户是否登录系统,用户名从命令行输入,如果指定的用户已经登录,则显示相关信息。

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

while :

do

    if w|sed \'1\'d|awk \'{print $1}\'|grep -qw "$1"

    then

       echo "用户$1 已经登录系统."

       exit

    fi

    sleep 300

done

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

先普及一个小常识,我们用ps aux可以查看到进程的PID,而每个PID都会在/proc内产生。如果查看到的pid在proc内是没有的,则进程被人修改了,这就代表系统很有可能已经被入侵过了。

请用上面知识编写一个shell,定期检查下自己的系统是否被人入侵过

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

pp=$$

ps -elf |sed \'1\'d > /tmp/pid.txt

for pid in `awk -v ppn=$pp \'$5!=ppn {print $4}\' /tmp/pid.txt`

do

    if ! [ -d /proc/$pid ]

    then

       echo "系统中并没有pid为$pid的目录,需要检查。"

    fi   

done

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

想办法把文本里面每三行内容合并到一行

例如:1.txt内容

```

1

2

3

4

5

6

7

```

处理后应该是

```

1 2 3

4 5 6

7

``

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

n=1

cat $1 |while read line

do

    n1=$[$n%3]

    if [ $n1 -eq 0 ]

    then

       echo "$line"

    else

       echo -n "$line "

    fi

    n=$[$n+1]

done

```

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

想办法把文本里面每三行内容合并到一行

例如:1.txt内容

```

1

2

3

4

5

6

7

```

处理后应该是

```

1 2 3

4 5 6

7

```

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

n=1

cat $1 |while read line

do

    n1=$[$n%3]

    if [ $n1 -eq 0 ]

    then

       echo "$line"

    else

       echo -n "$line "

    fi

    n=$[$n+1]

done

```

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

写一个getinterface.sh 脚本可以接受选项[i,I],完成下面任务:

 

1)使用格式:getinterface.sh [-i interface | -I ip]

 

2)当用户使用-i选项时,显示指定网卡的IP地址;当用户使用-I选项时,显示其指定ip所属的网卡。

 

例:

sh getinterface.sh -i eth0  或者

 

sh getinterface.sh -I 192.168.0.1

 

3)当用户使用除[-i | -I]选项时,显示[-i interface | -I ip]此信息。

 

4)当用户指定信息不符合时,显示错误。(比如指定的eth0没有,而是eth1时)

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

ip add |awk -F \': \' \'$1 ~ "^[1-9]" {print $2}\' > /tmp/ifs.txt

get_ip()

{

    ip add show dev $1 |grep inet |awk \'{print $2}\' |awk -F \'/\' \'{print $1}\'

}

 

for eth in `cat /tmp/ifs.txt`

do

    myip=`get_ip $eth`

    if [ -z "$myip" ]

    then

       echo $eth

    else

       echo $eth $myip

    fi

done > /tmp/if_ip.txt

 

if [ $# -ne 2 ]

then

    echo "请输入正确的格式: bash $0 -i 网卡 或者 bash $0 -I ip"

    exit

fi

 

if [ $1 == "-i" ]

then

    if awk \'{print $1}\' /tmp/if_ip.txt |grep -qw $2

    then

       eth=$2

       ip1=`awk -v aeth=$eth \'$1==aeth\' /tmp/if_ip.txt|sed "s/$eth //"`

        echo "网卡$2的ip是 $ip1"

    else

       echo "你指定的网卡不对,系统中的网卡有:`cat /tmp/ifs.txt|xargs`"

       exit

    fi

elif [ $1 == "-I" ]

then

    if grep -qw " $2 "  /tmp/if_ip.txt

    then

       eth=`grep -w " $2 " /tmp/if_ip.txt|awk \'{print $1}\'`

        echo "IP $2对应的网卡是$eth"

    else

       echo "你指定的ip不对,系统中的IP有:`ip add |grep inet |awk \'{print $2}\'|awk -F \'/\' \'{print $1}\'|xargs`"

       exit

    fi

else

    echo "请输入正确的格式: bash $0 -i 网卡 或者 bash $0 -I ip"

fi

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

写一个脚本产生随机3位的数字,并且可以根据用户的输入参数来判断输出几组。 比如,脚本名字为 number3.sh。

 

执行方法:

 

1)bash  number3.sh  会产生一组3位数字。

 

2)bash number3.sh 10 会产生10组3位数字。

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

get_number()

{

    for i in `seq 0 2`

    do

        a[$i]=$[$RANDOM%10]

    done

    echo ${a[@]}|sed s\'/ //g\'

}

 

if [ $# -eq 0 ]

then

    get_number

elif [ $# -eq 1 ]

then

    n=`echo $1|sed \'s/[0-9]//g\'`

    if [ -n "$n" ]

    then

       echo "给定的参数必须是一个数字"

        exit

    fi

    for i in `seq 1 $1`

    do

        get_number

    done |xargs

else

    echo "格式不对,正确的是格式是sh $0 [n],这里的n是一个数字。"

fi

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

写一个shell,先判断是否安装httpd和mysql,没有安装进行安装,安装了检查是否启动服务,若没有启动则需要启动服务。

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

if_install()

{

    rpm -q $1 >/dev/null 2>/dev/null

    if [ $? -eq 0 ]

    then

       echo "$1已经安装"

       return 0

    else

       echo "$1没有安装"

       return 1

    fi

}

 

if_install httpd

if [ $? -eq 0 ]

then

    if ! pgrep httpd >/dev/null

    then

       service httpd start

    fi

else

    yum install -y httpd

fi

 

if_install mysql-server

if [ $? -eq 0 ]

then

    if ! pgrep mysqld >/dev/null

    then

       service mysqld start

    fi

else

    yum install -y mysql-server

fi

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

用shell脚本判断输入的日期是否合法。

 

比如20170110就是合法日期,20171332就不合法。

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

if [ $# -ne 1 ] || [ ${#1} -ne 8 ]

then

    echo "请输入正确的格式,sh $0 yyyymmdd"

    exit 1

fi

 

y=`echo ${1:0:4}`

m=`echo ${1:4:2}`

d=`echo ${1:6:2}`

 

if echo $d|grep -q "^0"

then

    d=`echo ${1:6:2}|sed \'s/^0//\'`

fi

 

if cal $m $y >/dev/null 2>/dev/null

then

    if ! cal $m $y|grep -qw "$d"

    then

       echo "你给的日期是不合法的"

    else

       echo "日期合法"

    fi

else

    echo "你给的日期不合法"

fi

 

```

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

写一个监控网卡的脚本,需要满足以下要求:

 

1. 每10分钟检测一次指定网卡的流量。

 

2. 如果流量为0,则重启网卡。

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

LANG=en

sar -n DEV 1 10|grep -w "$1" > /tmp/sar.tmp

in=`grep "Average:" /tmp/sar.tmp|awk \'{print $5}\'|sed \'s/\\.//\'`

out=`grep "Average:" /tmp/sar.tmp|awk \'{print $6}\'|sed \'s/\\.//\'`

 

if [ $in == "000" ] && [ $out == "000" ]

then

    ifdown $1

    ifup $1

fi

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

写一个shell脚本,通过curl -I 返回的状态码来判定所访问的网站是否正常。

比如,当状态码为200时,才算正常。

2、分析:

 

3、流程图:

 

 

4、实现:

#!/bin/bash

#这个脚本用来判断一个网址是否正常

#作者:猿课-阿铭 www.apelearn.com

#日期:2018-11-01

 

url="http://www.apelearn.com/index.php"

mail_user=306798658@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

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

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

2、分析:

 

3、流程图:

 

 

4、实现:

#!/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`

 

```

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

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

2、分析:

 

3、流程图:

 

 

4、实现:

#!/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

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

已知nginx访问的日志文件在/usr/local/nginx/logs/access.log内,请统计下早上10点到12点 来访ip最多的是哪个?

2、分析:

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”

```

3、流程图:

 

 

4、实现:

#!/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}\'

 

```

 

5、实现解析:

 

6、结果验证

 

 

 

 

1、问题:

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

 

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

2、分析:

 

3、流程图:

 

 

4、实现:

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

 

```

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

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

```

# This is a test file.

# Test insert line into this file.

```

2、分析:

 

3、流程图:

 

 

4、实现:

#!/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

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

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

2、分析:

 

3、流程图:

 

 

4、实现:

d1=`date +%d`

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

 

if [ $d1 == "01" ]

then

    cd /etc/

    tar czf /root/bak/$d2_etc.tar.gz ./

fi

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

 

1、问题:

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

2、分析:

 

3、流程图:

 

 

4、实现:

 

or w in `sed \'s/[^a-zA-Z]/ /g\' $1`

do

    echo $w

done |sort |uniq -c |sort -nr|head

 

```

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

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

2、分析:

              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

```

3、流程图:

 

 

4、实现:

#!/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

 

5、实现解析:

 

6、结果验证

 

 

 

 

 

1、问题:

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

2、分析:

 

3、流程图:

 

 

4、实现:

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

 

5、实现解析:

 

6、结果验证

 

以上是关于Shell案例的主要内容,如果未能解决你的问题,请参考以下文章

利用Shell开发跳板机功能脚本案例

Shell案例

shell编程

shell基础 变量 条件测试 判断结构

shell脚本——while循环语句(包含应用案例)

shell脚本案例批量创建用户