【1】

请按照这样的日期格式(xxxx-xx-xx)每日生成一个文件,
例如生成的文件名为2017-12-20.log,
并且把磁盘的使用情况写到到这个文件中,
不用考虑cron,仅仅写脚本即可
image.png

【2】

有日志1.log,部分内容如下
<br />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](http://formula-x.haotui.com/registerbbs.php)” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)”<br />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](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)”<br />
统计出每个IP访问量有多少

image.png

【3】

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

image.png

【4】

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

【5】

找到/123目录下所有后缀名为.txt的文件
1. 批量修改.txt为.txt.bak
2. 把所有.bak文件打包压缩为123.tar.gz
3. 批量还原文件的名字,即把增加的.bak再删除
image.png

【6】

写一个脚本,判断本机的80端口(假如服务为httpd)是否开启着,如果开启着什么都不做,如果发现端口不存在,那么重启一下httpd服务,
并发邮件通知你自己。脚本写好后,可以每一分钟执行一次,也可以写一个死循环的脚本,30s检测一次。

核心要点
检测80端口使用nmap -p 80 127.0.0.1或者netstat -lntp|grep -w 80
重启httpd服务的命令要知道
* 发邮件脚本依然使用mail.py

通过判断80端口是否开启,如果开启什么都不做,端口不存在的话重启一下httpd服务并发邮件通知自己。
image.png

【7】——————————————————————————————————————————————-

设计一个shell脚本来备份数据库,首先在本地服务器上保存一份数据,然后再远程拷贝一份,本地保存一周的数据,远程保存一个月。
假定,我们知道mysql root账号的密码,要备份的库为discuz,本地备份目录为/bak/mysql, 远程服务器ip为192.168.123.30,
远程提供了一个rsync服务,备份的地址是 192.168.123.30::backup . 写完脚本后,需要加入到cron中,每天凌晨3点执行。

【8】—————————————————————————————————————————————

服务器上跑的是LNMP环境,近期总是有502现象。502为网站访问的状态码,200正常,502错误是nginx最为普遍的错误状态码。

由于502只是暂时的,并且只要一重启php-fpm服务则502消失,但不重启的话,则会一直持续很长时间。

所以有必要写一个监控脚本,监控访问日志的状态码,一旦发生502,则自动重启一下php-fpm。

我们设定:

1)access_log /data/log/access.log

2)脚本死循环,每10s检测一次(假设每10s钟的日志条数为300左右)

3)重启php-fpm的方法是 /etc/init.d/php-fpm restart

【9】

把一个文本文档的前5行中包含字母的行删除掉,同时把6到10行中的全部字母删除掉
image.png

【10】

用shell打印下面这句话中字母数小于6的单词。
Bash also interprets a number of multi-character options.
###思路是使用for循环将这句话的每个词的字数统计出来,然后再使用if判断将小于6的词打印
image.png

【11】

写一个脚本实现如下功能:
输入一个数字,然后运行对应的一个命令。
显示命令如下:
cmd meau* 1 - date 2 - ls 3 - who 4 - pwd
当输入1时,会运行date, 输入2时运行ls, 以此类推。
##read -p在输入前打印提示信息
##case对用户输入的内容进行判断

  1. #!/bin/bash
  2. echo "*cmd meau** 1 - date 2 - ls 3 - who 4 - pwd"
  3. read -p "Please input a number: " n
  4. if [ -z "$n" ]
  5. then
  6. echo "请输入一个纯数字,范围1-4."
  7. exit
  8. fi
  9. n1=`echo $n|sed 's/[0-9]//g'`
  10. if [ -n "$n1" ]
  11. then
  12. echo "请输入一个纯数字,范围1-4."
  13. exit
  14. fi
  15. case $n in
  16. 1)
  17. date
  18. ;;
  19. 2)
  20. ls
  21. ;;
  22. 3)
  23. who
  24. ;;
  25. 4)
  26. pwd
  27. ;;
  28. *)
  29. echo "请输入1-4的数字"
  30. ;;
  31. esac

【12】

加user_00 – user_09 10个用户,并且给他们设置一个随机密码,密码要求10位包含大小写字母以及数字,注意需要把每个用户的密码记录到一个日志文件里。
##mkpasswd随机生成密码

#!/bin/bash
for i in `seq -w 00 09`
do
    useradd user_$i
    p=`mkpasswd -l 10 -s 0 `
    echo "user_$i $p" >> /tmp/pass.tmp
    echo $p |passwd --stdin user_$i
done

【13】—————————————————————————————————————————————————————————-

在服务器上,写一个监控脚本,要求如下:
1. 每隔10s去检测一次服务器上的httpd进程数,如果大于等于500的时候,就需要自动重启一下apache服务,并检测启动是否成功?
2. 若没有正常启动还需再一次启动,最大不成功数超过5次则需要立即发邮件通知管理员,并且以后不需要再检测!
3. 如果启动成功后,1分钟后再次检测httpd进程数,若正常则重复之前操作(每隔10s检测一次),若还是大于等于500,那放弃重启并需要发邮件给管理员,然后自动退出该脚本。假设其中发邮件脚本为之前使用的mail.py

【14】————————————————————————————————————————————————————————-

需求: 根据web服务器上的访问日志,把一些请求量非常高的ip给拒绝掉!并且每隔半小时把不再发起请求或者请求量很小的ip给解封。
假设:
1. 一分钟内请求量高于100次的IP视为不正常请求。
2. 访问日志路径为/data/logs/access_log。
用第2例中的1.log作为演示日志

【15】

请仔细查看如下几个数字的规律,并使用shell脚本输出后面的十个数字。
10 31 53 77 105 141 …….
###发现这个差值的差值是有规律的:
10 31 53 77 105 141
21 22 24 28 36
1 2 4 8

#! /bin/bash
x=21
m=10
echo $m
for i in `seq 0 14`; do
    j=$[2**$i]
    m=$[$m+$x]
    echo $m
    x=$[$x+$j]
done

【16】

写个shell,看看你的Linux系统中是否有自定义用户(普通用户),若是有,一共有几个?
##首先判断linux系统版本
##然后通过系统版本的uid判断超级用户和普通用户
##centos7普通用户1000-65535

#!/bin/bash
v=`awk -F 'release ' '{print $2}' /etc/redhat-release |cut -d '.' -f1`
user()
{
      if [ $1 -eq 0 ]
      then
          echo "系统没有自定义的用户"
      else
          echo "系统存在自定义用户,有$1个"
      fi
}
case $v in 
  5|6)
      n=`awk -F ':' '$3>=500' /etc/passwd|wc -l`
      user $n
  ;;
  7)
      n=`awk -F ':' '$3>=1000' /etc/passwd|wc -l`
      user $n
  ;;
  *)
     echo "脚本出错."
  ;;
esac

【17】

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

#!/bin/bash
dir=/tmp/disk
d=`date +%F`
mail=3240015684@qq.com

[ -d $dir ] || mkdir $dir

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

df|sed '1d' |awk -F ' +|%' '$5>=1 {print $7}' > $dir/df.tmp
df -i|sed '1d' |awk -F ' +|%' '$5>=1 {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

image.png

【18】————————————————————————————————————————————————————————

有一台服务器作为web应用,有一个目录(/data/web/attachment)不定时地会被用户上传新的文件,但是不知道什么时候会上传。所以,需要我们每5分钟做一次检测是否有新文件生成。
请写一个shell脚本去完成检测。检测完成后若是有新文件,还需要将新文件的列表输出到一个按年、月、日、时、分为名字的日志里。

【19】

使用sort命令删除重复行反向排序
##Uniq -c 在每列旁边显示该行重复出现的次数
##Head命令查看前10个

#!/bin/bash
cat ~/.bash_history |sort |uniq -c |sort -nr |head

【20】——————————————————————————————————————————————————————————————————

假如需要每小时都去执行一个脚本。在脚本中实现这样的功能,当时间是0点和12点时,需要将目录/data/log/下的文件全部清空,
注意只能清空文件内容而不能删除文件。而其他时间只需要统计一下每个文件的大小,一个文件一行,输出到一个按日期和时间为名字的日志里。
需要考虑/data/log/目录下的二级、三级、… 等子目录里面的文件。

【21】

计算文档a.txt中每一行中出现的数字个数并且要计算一下整个文档中一共出现了几个数字。例如a.txt内容如下:
12aa*lkjskdj
alskdflkskdjflkjj
我们脚本名字为 ncount.sh, 运行它时:
bash ncount.sh a.txt
输出结果应该为:
2
0
sum:2
##sed把非数字字符删除,计算长度
##for 循环计算总和

#!/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 < $1a.txt                                                  ##其中$1是 后面跟的文件    
echo "sum:$sum"

【22】——————————————————————————————————————————————————————-

有两台Linux服务器A和B,假如A可以直接ssh到B,不用输入密码。A和B都有一个目录叫做/data/web/ 这下面有很多文件,
当然我们不知道具体有几层子目录,假若之前A和B上该目录下的文件都是一模一样的。
但现在不确定是否一致了。固需要我们写一个脚本实现这样的功能,检测A机器和B机器/data/web/目录下文件的异同,我们以A机器上的文件作为标准。
比如,假若B机器少了一个a.txt文件,那我们应该能够检测出来,或者B机器上的b.txt文件有过改动,我们也应该能够检测出来(B机器上多了文件不用考虑)。

【23】——————————————————————————————————————————————————————-

写一个脚本,检测你的网络流量,并记录到一个日志里。需要按照如下格式,并且一分钟统计一次(只需要统计外网网卡,假设网卡名字为eth0):
2017-08-04 01:11
eth0 input: 1000bps
eth0 output : 200000bps
#### ############
2017-08-04 01:12
eth0 input: 1000bps
eth0 output : 200000bps

【24】

一台机器负载高,top查看有很多sh的进程,然后top -c查看可以看到对应的进程命令是sh -c /bin/clearnen.sh 。
经分析后发现是因为该脚本执行时间太长,导致后续执行时,上次的脚本还未执行结束。写一个脚本批量杀死所有sh的进程。
##kill -9 pid杀进程

#!/bin/bash

for p in `ps aux | grep clear.sh|awk '{print $2}'`
do
    kill -9 $p
done

【25】

写一个脚本判断你的Linux服务器里是否开启web服务?(监听80端口)如果开启了,请判断出跑的是什么服务,是httpd呢还是nginx又或者是其他的什么?
##过滤出80端口和服务的名字然后引用变量输出

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

【26】————————————————————————————————————————————————————————————

假设,当前MySQL服务的root密码为123456,写脚本检测MySQL服务是否正常(比如,可以正常进入mysql执行show processlist),
并检测一下当前的MySQL服务是主还是从,如果是从,请判断它的主从服务是否异常。如果是主,则不需要做什么。

【27】———————————————————————————————————————————————————————————

写一个支持选项的增加或删除用户的shell脚本,具体要求如下:
1. 只支持三个选项:’—del’,’—add’,’—help’,输入其他选项报错。
2. 使用’—add’时,需要验证用户名是否存在,存在则反馈存在,且不添加。 不存在则创建该用户,需要设置与该用户名相同的密码。
3. 使用’—del’时,需要验证用户名是否存在,存在则删除用户及其家目录。不存在则反馈该用户不存在。
4. —help选项反馈出使用方法。
5. 能用echo $?检测脚本执行情况,成功删除或添加用户为0,不成功为非0正整数。
6. 能以英文逗号分割,一次性添加或者删除多个用户。例如 adddel.sh —add user1,user2,user3

【28】

写一个脚本: 计算100以内所有能被3整除的正整数的和
##先定义一个sum
##使用for循环列出1到100的数
##定义一个算术式如果结果为0就把这个数加上累加记和

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

【29】

使用传参的方法写个脚本,实现加减乘除的功能。
例如: sh a.sh 1 2,这样会分别计算加、减、乘、除的结果。

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

【30】

写一个脚本,执行后,打印一行提示“Please input a number:”,要求用户输入数值,然后打印出该数值,然后再次要求用户输入数值。直到用户输入”end”停止。

#!/bin/bash
while :
do
    read -p "Please input a number: " n
    if [ -z "$n" ]
    then
    echo "请输入一个纯数字."
    continue
    fi
    if echo $n |grep -qi 'end'
    then
    exit
    fi
    n1=`echo $n|sed 's/[0-9]//g'`
    if [ -n "$n1" ]
    then
    echo "请输入一个纯数字."
        continue
    else
    echo "你输入的数字是: $n"
        continue
    fi
done

【31】———————————————————————————————————————————————————————————

提示用户输入网卡的名字,然后我们用脚本输出网卡的ip,需要考虑下面问题:
1. 输入的字符不符合网卡名字规范,怎么应对。
2. 名字符合规范,但是根本就没有这个网卡又怎么应对。

【32】

写一个脚本,实现如下功能:

1. 脚本可以带参数也可以不带
2. 参数可以有多个,每个参数必须是一个目录
3. 脚本检查参数个数,若等于0,则列出当前目录本身,否则显示每个参数包含的子目录。

#!/bin/bash
if [ $# -eq 0 ]
then
    echo "当前目录下的文件是:"
    ls .
else
    for d in $@
    do
    if [ -d $d ]
    then
        echo "目录$d下有这些子目录:"
        find $d -type d 
    else
        echo "并没有该目录:$d"
    fi
    done
fi

【33】

写一个猜数字脚本,当用户输入的数字和预设数字(随机生成一个0-100的数字)一样时,直接退出,否则让用户一直输入,并且提示用户的数字比预设数字大或者小。

#!/bin/bash
n=$[$RANDOM%101]
while :
do
    read -p "请输入一个0-100的数字:" n1
    if [ -z "$n1" ]
    then
    echo "必须要输入一个数字。"
    continue
    fi
    n2=`echo $n1 |sed 's/[0-9]//g'`
    if [ -n "$n2" ]
    then
    echo "你输入的数字并不是正整数."
    continue
    else
    if [ $n -gt $n1 ]
    then
        echo "你输入的数字小了,请重试。"
        continue
    elif [ $n -lt $n1 ]
    then
        echo "你输入的数字大了,请重试。"
        continue
    else
        echo "恭喜你,猜对了!"
        break
    fi
    fi
done