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案例的主要内容,如果未能解决你的问题,请参考以下文章