实例五十一【监控22端口是否被封】
需求:一个同学不小心用iptables规则把sshd端口22给封掉了,结果不能远程登陆,要想解决这问题,还要去机房,登陆真机去删除这规则。现在想要写一个监控脚本,监控iptables规则是否封掉了22端口,如果疯掉了,给打开。写好脚本,放到任务计划里,每分钟执行一次。
提示:
1、如何判断22端口被封掉
2、思路是查看iptables INPUT链规则,看是否有目标端口为22的规则,并且规则target为DROP或者REJECT
#!/bin/bash
iptables -nvL INPUT --line-numbers |grep -w 'dpt:22' |awk '$4 ~/REJECT|DROP/ {print $1}' > /tmp/iptables.log
n=`cat /tmp/iptables.log |wc -l`
if [ $n -gt 0 ]
then
for n in `tac /tmp/iptables.log`
do
iptables -D INPUT $n
done
fi
脚本解析:
1、iptables -nvL INPUT --line-numbers >此命令是获取服务器防火墙进站的规则
2、grep -w 'dpt:22' >获取与22端口有关的规则
3、awk '$4 ~/REJECT|DROP/ {print $1}' >将管道传入的每一条规则中,只要每条规则的第四个字段(模糊)匹配REJECT|DROP字符串,那么将该条规则的第一个字段,也就是此规则的编号导出到文档/tmp/iptables中
4、iptables -D INPUT $n >此命令是将编号为$n的规则删除掉
5、如何配置任务计划,这点将在后续的内容中展开来说明
实例五十二:【打印数字】
需求:写一个shell脚本。提示输入一个暂停的数字,然后从1打印到该数字。然后询问是否继续。继续的话再输入一个数字接着打印,否则退出脚本。
例:如果输入的是5,打印1 2 3 4 5,然后继续输入15,然后打印6 7 8 ...14 15依次类推。
提示:
1、根据题目要求,首先用read -p 提示用户输入一个数字,获取到第一个数字
2、此时需要判断用户输入的是否是纯数字
3、第一次循环后,若用户继续输入数字,此时不仅要判断输入的是否是纯数字,还要判断输入的数字是否比第一个数字大。
#!/bin/bash
#
declare -i first=1
flag=true
while [ $flag != 'quit' ]
do
read -t 10 -p "please input a number:" num
if [ $num = 'quit' ];then
echo "leaving"
exit 0
fi
zj=`echo "$num"|sed 's/[0-9]//g'`
if [ -z $zj ];then
while [ $first -le $num ]
do
echo "$first "
first=$[$first+1]
done
else
echo "请输入一个正整数:"
fi
done
脚本解析:
1、declare -i first=1 >由于脚本需要从1开始打印,所以先定义一个初始值
2、while [ $flag != 'quit' ] >根据自定义的标志变量进入死循环,其实可以直接使用"while :"进入死循环
实例五十三:【增加文件内容】
需求:在文本文档1.txt第5行(假设文件行数大于5)后面增加如下内容:
#This is a test file
#Test insert line into this file.
提示:
1、给文档指定行后面增加内容,可以使用sed搞定
2、比较笨的方法是,依次按顺序打印前5行,然后打印要增加的行,再从文本第6行开始一直打印到结束。
cat test|sed '5a #This is a test file\n#Test insert line into this file.'
脚本解析:
1、sed '5a #This is a test file\n#Test insert line into this file.' >在传入文本流中的第五行开始追加【append】后续的内容,其中"\n"是换行的意思
实例五十四:【备份/etc目录】
需求:设计一个shell程序,在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名为如下形式"yymmdd_etc.tar.gz",yy为年,mm为月,dd为日。
提示:
1、yymmdd用date +%y%m%d表示
2、每月第一天,需要判断date +%d是否是01
#!/bin/bash
#这个脚本用来备份/etc/目录
#
d1=`date +%d`
d2=`date +%y%m%d`
if [ $d1 == "01" ]
then
cd /etc/
tar -czf "/root/bak/${d2}_etc.tar.gz" ./
fi
脚本解析:
1、tar -czf "/root/bak/${d2}_etc.tar.gz" ./ >此命令是将当前目录"./"压缩为"/root/bak/${d2}_etc.tar.gz"
实例五十五:【找出重复的单词】
需求:将文件内所有的单词的重复次数计算出来,只需要列出重复次数最多的10个单词
提示:
1、把非英文的字符删除掉(用空格替换),剩余的就是英文单词或者字母
#!/bin/bash
#这个脚本用来找出重复的单词
#作者:SYJ
for w in `sed 's/[^a-zA-Z]/ /g' $1`
do
echo $w
done |sort |uniq -c |sort -nr |head
脚本解析:
1、for w in `sed 's/[^a-zA-Z]/ /g' $1` >此处是使用脚本传参,$1是需要检查的文档;作用是将文档中每一行的所有非英文字符使用"空格符"替换
2、done |sort |uniq -c |sort -nr |head >此处的作用是将for循环命令的所有输出,先使用sort排序,然后使用uniq进行统计,sort -nr是将统计后的内容根据数字进行反向排序;head命令默认输出前10行
实例五十六:【人员分组】
需求:把所有的成员平均分成若干个小组,这里提供一个人员列表,比如成员有50人,需要分成7个小组,要求随机性,每次和每次分组的结果应该不一致。
提示:
1、此题建议亲自动手做一遍
#!/bin/bash
#将50人平均分成7个小组
#
declare -A aa
declare -A bb
declare -A cc
declare -A dd
declare -A ee
declare -A ff
declare -A gg
echo "">user.tmp
for name in `cat user.txt`
do
echo $name >>user.tmp
done
declare -i haoma=0
[ -f num.txt ] && echo "" >num.txt || touch num.txt
while [ `cat num.txt|wc -l` -le 50 ]
do
num=$[$RANDOM%7]
hang_num=`grep $num num.txt|wc -l`
if [ $hang_num -le 7 ];then
haoma=$[$haoma+1]
echo "$haoma"
echo "************"
echo "$num" >>num.txt
case $num in
0)
namm=`sed -n "$haoma"p user.tmp`
aa[$hang_num]=$namm;;
1)
namm=`sed -n "$haoma"p user.tmp`
bb[$hang_num]=$namm;;
2)
namm=`sed -n "$haoma"p user.tmp`
cc[$hang_num]=$namm;;
3)
namm=`sed -n "$haoma"p user.tmp`
dd[$hang_num]=$namm;;
4)
namm=`sed -n "$haoma"p user.tmp`
ee[$hang_num]=$namm;;
5)
namm=`sed -n "$haoma"p user.tmp`
ff[$hang_num]=$namm;;
6)
namm=`sed -n "$haoma"p user.tmp`
gg[$hang_num]=$namm;;
esac
else
echo "undo"
fi
done
echo "${aa[@]}"
echo "${#aa[@]}"
echo "#########"
echo "${bb[@]}"
echo "${#bb[@]}"
echo "#########"
echo "${cc[@]}"
echo "${#cc[@]}"
echo "#########"
echo "${dd[@]}"
echo "${#dd[@]}"
echo "#########"
echo "${ee[@]}"
echo "${#ee[@]}"
echo "#########"
echo "${ff[@]}"
echo "${#ff[@]}"
echo "#########"
echo "${gg[@]}"
echo "${#gg[@]}"
脚本解析:
1、declare -A aa >此命令是声明一个名称为aa的数组
2、echo "">user.tmp >创建一个空的文档用来存放用户【以一行一个用户名的方式存放】
3、declare -i haoma=0;haoma=$[$haoma+1];namm=`sed -n "$haoma"p user.tmp`;这三条命令是确保user.tmp中每个用户都被放到了数组中
4、aa[$hang_num]=$namm >将变量$namm赋值给下标为$hang_num的数组aa元素
5、echo "${aa[@]}" >此命令是列出数组aa中的元素
6、echo "${#aa[@]}" >此命令是显示数组aa中的元素个数
实例五十七:【比较两个数大小】
需求:写一个shell脚本,比较两个数的大小,支持浮点数,两个数通过shell参数的形式提供
提示:
1、bc是shell中主要支持浮点数的大小比较
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
脚本解析:
1、if echo $1|grep -q '^-' >此命令意思是如果$1是以"-"开头则进入then语句;否则进入else语句;作用去掉数字开头的负号
2、n=`echo $nu|sed 's/[0-9.]//g'` >此命令的意思是将变量$nu中的数字及"."去掉;作用验证变量是否为合法数字
3、 if echo $1|grep -q '^\.' >此命令的意思是如果变量$1是以小数点开头则进入then语句;否则进入else语句;其中"\."是转译
4、此脚本没有考虑到如果数字内含有两个小数点这种非法数字
实例五十八:【批量新建文档】
需求:使用for循环在/oldboy目录下通过随机小写10个字母加固定字符串oldboy批量创建10个html文件,名称例如为:
coaolvajcq_oldboy.html qnvuxvicni_oldboy.html vioesjmcbu_oldboy.html
#!/bin/bash
#批量新建文档
#
for f in `seq 1 10`
do
str=`uuidgen`
str1=`echo "$str"|sed 's#-##g'|cut -b -8`
echo "$str1"
bastr=oldboy.html
touch $str1_$bastr
done
脚本解析:
1、str1=`echo "$str"|sed 's#-##g'|cut -b -8` >此命令是截取长度为8的字符串
实例五十九:【找文件差异】
需求:有两个文件a.txt和b.txt,把a.txt中有的但b.txt中没有的行找出来,并写入到c.txt,然后计算出c.txt文件的行数
提示:
1、使用while循环遍历a.txt,逐行进行匹配,如果这一行在b.txt中没有就重定向到c.txt
#!/bin/bash
#这个脚本用来比较文件差异
#
cat a.txt|while read line
do
if ! grep -q "$line" b.txt
then
echo $line
fi
done > c.txt
wc -l c.txt
脚本解析:
1、done > c.txt >此命令是将循环中所有的导出到终端的内容重定向到c.txt
实例六十:【杀进程】
需求:把当前用户下所有进程名字中含有"aming"的进程关闭
提示:
1、ps -u $USER
ps -u $USER|awk '$NF ~ /kworker/ {print $1}' |xargs kill
脚本解析:
1、ps -u $USER >显示由当前用户发起的所有进程信息
2、awk '$NF ~ /kworker/ {print $1}' >将最后一列【及最后一个字段】中含有字符"kworker"的行的第一个字段输出
3、xargs kill >杀死由管道传过来的进程号