服务器上,多多少少都会有一些日志文件,nginx python等等诸如此类,运行时间一长,难免会遇到磁盘塞满的状况,由于缺乏适当的日志清空机制(nginx也许要写个脚本跑),这时候就需要手动去删除一部分日志腾出空间,但是对于我这种懒人,要管理这么多服务器,时不时就需要去清空下日志,简直受不了,于是了解了下管道和awk,自己尝试着写了个简单的shell脚本
不想看过程请直接跳到最后的解决方案
首先,我们需要列出这次需要考虑的几个问题
1.在sheel中如何声明变量并使用
2.管道是什么
3.AWK又是个什么
4.怎么在一句代码中进行判断和后续处理
在sheel中如何声明变量并使用
其实这个是一个很入门的东西了,不过这里也简单的提一下,shell中声明变量和大部分语言一样使用loli='yes'
的方式进行声明,不过需要注意,等号前后不能有空格
,还有一些常识,都列(fu)举(zhi)一下
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线(_)。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。
如何使用呢?其实也很简单,echo $loli
或者echo ${loli}
都是可以的。
管道是什么
复制大神的话,管道命令操作符是:”|”,它仅能处理经由前面一个指令传出的正确输出信息,也就是 standard output 的信息,对于 stdandard error 信息没有直接处理能力。然后,传递给下一个命令,作为标准的输入 standard input.
是不是有点懵逼,简单地讲,管道就是将前一个命令的内容,传递给下一个命令,比如ps aux | grep python3
,是不是很熟悉?ps aux可以输出当前所有正在运行的进程信息,这里通过管道的操作符|,将ps aux的标准输出,传递给了grep,grep是一个用于处理文本查找常用指令,这里就是使用grep筛选出来了包含python3字符串的列,只有符合这个列的数据才会打印出来。
比如ps aux
输出如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
root 868 0.0 0.1 301712 29452 ? Sl Oct16 21:25 python3 /home/main.py --port=12024 root 874 0.0 0.1 301712 29472 ? Sl Oct16 21:36 python3 /home/main.py --port=12025 xiaoc 1934 1.7 0.4 166536 79144 ? S Dec13 131:21 nginx: worker process xiaoc 1935 1.7 0.5 170632 83944 ? S Dec13 130:57 nginx: worker process xiaoc 1936 1.7 0.4 169608 81512 ? S Dec13 131:58 nginx: worker process xiaoc 1937 1.8 0.4 170632 82336 ? S Dec13 132:37 nginx: worker process xiaoc 1938 1.8 0.4 168584 81112 ? S Dec13 136:01 nginx: worker process xiaoc 1939 1.7 0.4 168456 80736 ? S Dec13 131:41 nginx: worker process xiaoc 1940 1.7 0.4 167560 80528 ? S Dec13 131:40 nginx: worker process xiaoc 1941 1.7 0.4 167560 79752 ? S Dec13 131:07 nginx: worker process xiaoc 1942 0.0 0.0 121992 15232 ? S Dec13 1:22 nginx: cache manager process root 3467 0.0 0.0 0 0 ? S 12:28 0:00 [kworker/u8:1] root 4884 0.0 0.0 46784 2852 tty1 S Dec09 0:00 su root root 4922 0.0 0.0 13740 3392 tty1 S+ Dec09 0:00 bash root 5249 0.0 0.0 42240 2756 ? S 12:30 0:00 /usr/sbin/CRON -f root 5250 0.0 0.0 42240 2808 ? S 12:30 0:00 /usr/sbin/CRON -f root 5251 0.0 0.0 42240 2808 ? S 12:30 0:00 /usr/sbin/CRON -f root 5252 0.0 0.0 42240 2772 ? S 12:30 0:00 /usr/sbin/CRON -f |
那么ps aux | grep python3
将会输出
1 2 3 |
root 868 0.0 0.1 301712 29452 ? Sl Oct16 21:25 python3 /home/main.py --port=12024 root 874 0.0 0.1 301712 29472 ? Sl Oct16 21:36 python3 /home/main.py --port=12025 |
AWK又是个什么
你只需要知道,AWK是一个超级强大的文本分析工具
!
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。
awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。
怎么在一句代码中进行判断和后续处理
这就要借助强大的awk了,比如我们需要将当前目录下,超过102400字节的文件打印出来,那么就可以这样写
1 2 |
ls -la | awk '{if($5 > 102400) print $0}' |
别急,这里简单的说一下awk干了什么,以及那个$5和$0又是个什么东西。
我们先是用了ls -la输出了当前所有文件和文件夹,然后使用管道(|)将输出的数据传递给了awk,由于awk是逐行处理,以空格为默认分隔符将每行切片
,所以这里的$5就代表一行的第5个切片,$1就是第1个切片,可能会觉得疑问,索引不都是从0开始的吗?在awk里面比较特殊,$0是代表当前这一行的所有数据
。
也可以写成这样
1 2 3 |
max_length=1024000 ls -la | awk '{if($5 > '"$max_length"') print $0}' |
是不是看着有点懵逼,这个单引号双引号$max_length双引号单引号
又是个什么鬼?
会产生这样的问题,是因为这里和平时用到的语言有点不太一样
比如平时需要将2个字符串相加,一般情况下是print "a" + "b",这样输出ab
,然而在awk中,却是这样的
1 2 3 |
ls -la | awk '{print "a""b"}' ls -la | awk '{print "a"+"b"}' //输出并不是ab |
没错,在awk中,字符串之间不需要用+号连接起来,就像c#的$语法糖和python3.6的f语法糖一样,直接在字符串中写变量就好了,只是将{}变成了双引号。(感觉好像并没有讲懂,反正要在awk中用外部变量,这么用就对了)
现在判断做好了,然后需要怎么处理呢
现在就需要用到wak的system函数去调用shell命令
1 2 |
ls -la | awk '{if($5 > 102400)system("echo del file:" $9)}' |
这样符合条件的文件,就会被打印出来,显示del file: xxxxx
同样的,我们使用
1 2 |
ls -la | awk '{if($5 > 102400)system("echo del file:" $9 "; echo \"\">"$9)}' |
就可以直接将这个文件清空了!
最后我们再完善一下这句代码
1 2 |
cat dir_list.txt | awk '{system("ls -la " $1)}' | awk '{if($5 > '"$max_length"')system("echo file del: " $9 "; echo \"\">"$9 )}' |
这样就会直接读取当前目录下的dir_list.txt里面配置好的路径,然后判断并删除!
dir_list.txt文件示例如下
1 2 3 4 |
/tmp/xxx/xx/*.log.* /var/log/mongodb/*.log /var/log/xxx/*.log.* |
最后的最后,再完善一下
1 2 3 4 5 6 7 8 9 10 11 12 13 |
max_length=1073741824 echo '' df -h | awk '{if($1~/^\/dev/)print "dev:" $1 ", use:" $2"/"$3"("$5")"}' echo '' echo 'clear start' echo '-----------------------------------------------------------------------' cat dir_list.txt | awk '{system("ls -la " $1)}' | awk '{if($5 > '"$max_length"')system("echo file del: " $9 "; echo \"\">"$9 )}' echo '-----------------------------------------------------------------------' echo 'clear end' echo '' df -h | awk '{if($1~/^\/dev/)print "dev:" $1 ", use:" $2"/"$3"("$5")"}' echo '' |
效果图