21.计算数字个数
需求:
- 计算文档a.txt中每一行中出现的数字个数并且要计算一下整个文档中一个出现了几个数字。
- 例如a.txt内容如下:
- 12aa*lkjskdj
- alskdflkskdjfljkk
- 我们的脚本名字为ncount.sh,运行时:bash ncount.sh a.txt 输出结果:2 0 sum:2
核心要点:
- sed把非数字字符删除,计算长度
- for循环计算总和
[root@localhost ~]# cat a.txt
12aa*lkjskdj
alskdflkskdjfljkk
[root@localhost ~]# sh -x ncount.sh a.txt
+ sum=0
+ read line
++ wc -l
++ sed 's/[^0-9]//'
++ echo '12aa*lkjskdj'
+ line_n=1
+ echo 1
1
+ sum=1
+ read line
++ wc -l
++ sed 's/[^0-9]//'
++ echo alskdflkskdjfljkk
+ line_n=1
+ echo 1
1
+ sum=2
+ read line
+ echo sum:2
sum:2
[root@localhost ~]# cat ncount.sh
#!/bin/bash
sum=0
while read line ######while read line 是一次性将文件信息读入并赋值给变量line ,while中使用重定向机制,文件中的所有信息都被读入并重定向给了整个while 语句中的line 变量。####
do
line_n=`echo $line|sed 's/[^0-9]//'|wc -l`
echo $line_n
sum=$[$sum+$line_n]
done < $1
echo "sum:$sum"
[root@localhost ~]#
##########################################################
while read line
do
…
done < file
刚开始看到这种结构时,很难理解< file是如何与循环配合在一起工作的。因为循环内有很多条命令,而我们之前接触的重定向都是为一条命令工作的。这里有一个原则,这个原则掌握好了,这个问题就很简单了:
对循环重定向的输入可适用于循环中的所有需要从标准输入读取数据的命令;
对循环重定向的输出可适用于循环中的所有需要向标准输出写入数据的命令;
当在循环内部显式地使用输入或输出重定向,内部重定向覆盖外部重定向。
上面的while结构中,read命令是需要从标准输入中读取数据的。我们来详细了解一下read命令的用法吧,这个命令是shell脚本中使用频率最高的命令之一。
22.对比文件差异
需求:
- 有两台linux服务器A和B,加入A可以直接ssh到B,不用输入密码。A和B都有一个目录/data/web/下面有很多文件,我们不知道具体有几层,但假设该目录下的文件都是一模一样的,但现在不确定是否一直。脚本要求:检测AB/data/web/目录下的以同,以A机器上的文件为标准。B少了一个文件,或B上的文件有改动,我们都应该能够检测出来(多了不考虑)
核心要点:
- md5sum file #是要文件内容一样,md5sum的值也一样
- ssh B “ls /” #没有密码的情况下使用ssh远程执行命令
[root@localhost ~]# cat 22.sh
#!/bin.bash
dir=/data/web
[ -f /tmp/md5.list ] && rm -f /tmp/md5.list
find $dir/ -type f > /tmp/file.list
n=\`wc -l /tmp/md5.list|awk '{print \$1}'\`
for i in `seq 1 \$n`
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
while read line
do
file_name=\`sed -n "\$1"p /tm/md5.list |awk '{print \$1}'\`
md5=\`echo \$line|awk '{print \$2}'\`
if [ -f \$file_name ]
then
md5_b=\`md5sum \$file_name\`
if [ \$md5_b != \$md5 ]
then
echo "\$file_name changed."
else
echo"\$file_name lose."
fi
done < /tmp/md5.list
EOF
scp /tmp/check_md5.sh B:/tmp/
ssh B "/bin/bash /tmp/check_md5.sh"
[root@localhost ~]#
23.检测网卡流量
需求:写一个脚本检测网卡流量,并记录到一个日志里。需要按照如下格式,并且每分钟统计一次(秩序统计外网网卡,加入网卡名字eth0):
- 2017-08-04 01:11
- eth0 input:1000bps
- eth0 output:200000bps
- #############
- 2017-08-04 01:12
- eth0 input:1000bps
- eth0 output:200000bps
- 提示:使用sar -n DEV 1 59 这样可以统计一分钟的平均网卡流量,只需要最后面的平均值。另外,注意换算一下,1=Byte=8bit
核心要点:
- sar命令
- awk格式化输出
[root@localhost ~]# cat 23.sh
#!/bin/bash
logdir=/tmp/sar_log
file=$logdir/`date +%d%H`.log
t=`date +"%F %H:%M"`
[ -d $logdir ] || mkdir -p $logdir
LANG=en
sar -n DEV 1 59 | grep eth0 | grep "Average" > /tmp/sar.tmp
exec >> $file
echo "$t"
awk '{print "eth0 input:",$5*8000"bps""\n""eth0 output:",$6*8000"bps"}' /tmp/sar.tmp
echo "######################"
[root@localhost ~]#
24.批量杀进程
需求:
- 一台机器高负荷,top查看,有很多sh进程,然后top -c可以看到对应的进程命令是sh -c /bin/clearnen.sh。
- 经分析后发现是因为该脚本执行时间太长,导致后续执行时,上次的脚本还未执行结束。写一个脚本批量杀死所有的sh的进程
核心要点:
- kill -9 pid
[root@localhost ~]# cat 24.sh
#!/bin/bash
for pid in `ps aux|grep clearnen.sh |awk '{print $2}'`
do
echo $pid
kill -9 $pid
done
[root@localhost ~]#
25.判断web服务
需求:
- 写一个脚本判断Linux服务器里是否开启web服务?(监听80端口)如果开启了,请判断出跑的是什么服务是httpd还是nginx又或者是其他的什么
核心要点:
- netstat -lnpt | grep ':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}'`
echo "It is listenning port 80,and the service is $ser."
fi