每天两个shell脚本

1:要求:

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

#!/bin/bash
day=`date +%F`
mkdir /var/log/disk
df -h > /var/log/disk/$day.log

2:有日志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的访问量有多少?

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

3:需求:

写一个脚本计算一下linux系统所有进程占用内存大小的和。(提示,使用ps或者top命令)

#!/bin/bash
ps axu |grep -v 'RSS' | awk '{tot=tot+$6};END {print tot}'

或者

#!/bin/bash
sum=0
for i in `ps aux |grep -v 'RSS' |awk '{print $6}'`
do
sum=$[$sum+$i]
done
echo $sum

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

提示:

  1. 你可以使用ping命令 ping -c10 123.23.11.21
  2. 发邮件脚本可以参考 https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D22Z/mail.py
  3. 脚本可以搞成死循环,每隔30s检测一次
#!/bin/bash
while true
do
num=`ping -c 10 106.13.219.104 |grep received |awk -F '[ |,]' '{print $8}'`
if [ "$num" == "100%" ]
then
echo "down"   //这一步可以改成发邮件的脚本
fi
sleep 30   
done

或者:

#!/bin/bash

ip=123.23.11.21
ma=abc@139.com

while 1

do
ping -c10 $ip >/dev/null 2>/dev/null
if [ $? != “0” ];then
python /usr/local/sbin/mail.py $ma$ip down” “$ip is down”

#假设mail.py已经编写并设置好了
fi
sleep 30
done

5.需求:

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

#!/bin/bash
find /123 -type f -name "*.txt" > /tmp/txt.list
for i in `cat /tmp/txt.list`
do
    mv $i $i.bak
done
d=`date "+%y%m%d%H%M%S"`
mkdir /tmp/123_$d
for f in `cat /tmp/txt.list`
do
cp $f.bak /tmp/123_$d/
done
cd /tmp
tar -zcvf 123.tar.gz /tmp/123_$d/

for f in `cat /tmp/txt.list`
do
mv $f.bak $f
done

6.需求:

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

#! /bin/bash
mail=123@123.com
if netstat -lnp |grep ‘:80’ |grep -q ‘LISTEN’; then
exit
else
/usr/local/apache2/bin/apachectl restart >/dev/null 2> /dev/null
python mail.py $mail “check_80” “The 80 port is down.”
n=`ps aux |grep httpd|grep -cv grep`
if [ $n -eq 0 ]; then
/usr/local/apache2/bin/apachectl start 2>/tmp/apache_start.err
fi
if [ -s /tmp/apache_start.err ]; then
python mail.py  $mail  ‘apache_start_error’   `cat /tmp/apache_start.err`
fi
fi

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

#!/bin/bash
local=`date +%w`
remove=`date +%d`
exec 1> /var/log/mysqlbak.log 2> /var/log/mysqlbak.log
echo "mysql backup begin at `date +"%F %T"`."
mysqldump -uroot -p123457 --default-character-set=gbk discuz > /bak/mysql/discuz_$local.log
rsync -av /bak/mysql/discuz_$local.sql 192.168.247.30::backup/discuz_$remove.log
echo "mysql backup end at `date +"%F %T"`."

然后创建一个cron:

0 3 * * * /bin/bash /usr/local/sbin/shell/backup.sh

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

#! /bin/bash

log=/data/log/access.log

N=10

while :; do

##因为10秒钟大概产生300条日志

tail -n 300 $log > /tmp/log

n_502=`grep -c ‘ 502″‘ /tmp/log`

if [ $n_502 -ge $N ]; then

##记录系统的状态

top -bn1 >/tmp/`date +%H%M%S`-top.log

vmstat 1 5 >/tmp/`date +%H%M%S`-vm.log

/etc/init.d/php-fpm restart 2>/dev/null

##重启php-fpm服务后,应先暂缓1分钟,而后继续每隔10s检测一次

sleep 60

fi

sleep 10

done

9.要求:
把一个文本文档的前5行中包含字母的行删除掉,同时把6到10行中的全部字母删除掉。

参考答案:

假设文本名字叫做passwd,并且文本行数大于10,脚本如下

#!/bin/bash
nu=`wc -l passwd |awk '{print $1}'`
for i in `seq 1 5`
do
I=`sed -n "$i"p passwd`
if echo $I | grep -vq '[a-zA-Z]'
then
echo $I >> 1.txt
fi
done
for i in `seq 6 10`
do
I=`sed -n "$i"p passwd`
echo $I | sed 's/[a-zA-Z]//g' >> 1.txt
done
for i in `seq 11 $nu`
do
sed -n "$i"p passwd >> 1.txt
done
rm passwd
mv 1.txt passwd
##若想把更改内容写入到passwd,还需要把以上内容重定向到一个文本中,然后删除passwd,再把刚刚重定向的文件更名为passwd

10.用shell打印下面这句话中字母数小于6的单词。
Bash also interprets a number of multi-character options.

#!/bin/bash
num=`wc -w 1.txt|awk '{print $1}'`
for i in `seq 1 $num`
do
char_num=`cut -d ' ' -f $i 1.txt|wc -m`
if [ $char_num -lt 7 ]
then
cut -d ' ' -f $i 1.txt
fi
done

或者

#!/bin/bash
for i in Bash also interprets a number of multi-character options 
do
n=`echo $i |wc -c`
if [ $n -lt 7 ]
then
echo $i
fi
done

11.写一个脚本实现如下功能: 输入一个数字,然后运行对应的一个命令。显示命令如下:cmd meau* 1—date 2–ls 3–who 4–pwd
当输入1时,会运行date, 输入2时运行ls, 依此类推。

#!/bin/bash
read -p "cmd meau: 1-date 2-ls 3-who 4-pwd " tag
case $tag in
     1)
        date
        ;;
     2)
        ls
        ;;
     3)
        who
        ;;
     4)
        pwd
        ;;
     *)
        echo "Please input the number 1-4"
        ;;
esac

12.用shell脚本实现如下需求:
添加user_00 – user_09 10个用户,并且给他们设置一个随机密码,密码要求10位包含大小写字母以及数字,注意需要把每个用户的密码记录到一个日志文件里。

提示:
1. 随机密码使用命令 mkpasswd
2. 在脚本中给用户设置密码,可以使用echo 然后管道passwd命令

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

或者
#!/bin/bash
for u in `seq 0 9`
do
    useradd user_0$u
    if [ $? == 0 ]
    then
         password=`mkpasswd -l 10 -c 2 -C 2 -d 2`
         echo $password >> 1.txt
         echo $password |passwd --stdin user_0$u > /dev/null
    else
         echo "break"
         break
    fi
done

13.在服务器上,写一个监控脚本。

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

#!/bin/bash
i=1
while :
do
num=`ps aux |grep httpd |grep -cv 'grep'`
if [ $num -ge 500 ]
then
    systemctl restart httpd > /dev/null
    if [ $? != 0 ]
    then
        i=$[$i+1]
    else
        sleep 10
        num2=`ps aux |grep httpd |grep -cv 'grep'`
        if [ $num2 -lt 500 ]
        then
            sleep 60
        else
            echo "sh mail.py"
            exit
        fi
     fi
     echo "$i"
     if [ $i -eq 5 ]
     then
         echo "sh mail.by"
         exit
     fi
fi
sleep 10
done
#发邮件脚本我用echo “sh mail.py”代替表示

14.需求: 根据web服务器上的访问日志,把一些请求量非常高的ip给拒绝掉!

分析: 我们要做的,不仅是要找到哪些ip请求量不合法,并且还要每隔一段时间把之前封掉的ip(若不再继续请求了)给解封。 所以该脚本的关键点在于定一个合适的时间段和阈值。

比如, 我们可以每一分钟去查看一下日志,把上一分钟的日志给过滤出来分析,并且只要请求的ip数量超过100次那么就直接封掉。 而解封的时间又规定为每半小时分析一次,把几乎没有请求量的ip给解封!

参考日志文件片段:

157.55.39.107 [20/Mar/2015:00:01:24 +0800] www.aminglinux.com “/bbs/thread-5622-3-1.html” 200 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
61.240.150.37 [20/Mar/2015:00:01:34 +0800] www.aminglinux.com “/bbs/search.php?mod=forum&srchtxt=LNMP&formhash=8f0c7da9&searchsubmit=true&source=hotsearch” 200 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”

#!/bin/bash
d1=`date -d "-1 minute" +%H:%M`
ips=/tmp/ips.txt
ipt=/sbin/iptables
d2=`date +%M`
block(){
    grep "$d1" /var/log/nginx/access.log |awk '{print $1}'|sort -n|uniq -c|sort -n>$ips
    for ip in `awk '$1>50 {print $2}' $ips`
    do
        $ipt -I INPUT -p tcp --dport 80 -s $ip -j REJECT
        echo "`date +%F-%T` $ip" >> /tmp/badip.txt
        done
}

unblock(){
    for i in `ipt -nvL --line-numbers|grep '0.0.0.0/0'|awk '$2<15 {print $1}'|sort -nr`
    do
        $ipt -D INPUT $i
    done
    $ipt -Z
}

if [ $d2 == "00" ] || [ $d2 == "30" ]
then
    unblock
    block
else
    block
fi

15.请详细查看如下几个数字的规律,并使用shell脚本输出后面的十个数字。
10 31 53 77 105 141 …….
试题解析:
我想大多数人都会去比较这些数字的差值:
10 31 53 77 105 141
21 22 24 28 36
但是这个差值看,并没有什么规律,而我们再仔细看的时候,发现这个差值的差值是有规律的:
10 31 53 77 105 141
21 22 24 28 36
1 2 4 8

#!/bin/bash
a=32
b=52
c=141
i=1
while [ $i -lt 11 ]
do
    c=$[$b+$c]
    b=$[$b+$a]
    a=$[$a*2]
    i=$[$i+1]
    echo "$c"
done

16.写个shell,看看你的Linux系统中是否有自定义用户(普通用户),若是有,一共有几个?

参考答案:
假设所有普通用户都是uid大于1000的

#!/bin/bash
n=`awk -F ':' '$3>=1000' /etc/passwd|wc -l`
if [ $n -gt 0 ]
then
    echo "There are $n members."
else
    echo "no members."
fi

17.写一个shell脚本,检测所有磁盘分区使用率和inode使用率并记录到以当天日期为命名的日志文件里,当发现某个分区容量或者inode使用量大于85%时,发邮件通知你自己。
思路:就是先df -h 然后过滤出已使用的那一列,然后再想办法过滤出百分比的整数部分,然后和85去比较,同理,inode也是一样的思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值