脚本背景
老总最近总是发现某台relay服务器的CPU值会突然彪很高,于是勒令几位工程师检查问题,但是工程师一时半会也想不到究竟是什么程序这么耗费CPU,于是就委托运维写一个脚本,具体要求是这样的:每隔一秒钟输出一下top命令的前十二行情况(其实就是配置总览和耗费cpu前五名程序情况),将这些情况保存到一个文件里,如果这个文件大于500MB,就把这个文件删除(为啥要删除?我也不知道),重新再生成一个文件用来保存top命令结果。
分析
由于脚本无法自己跳出运行并检查自己的大小,所以这个任务需要两个脚本,一个是单纯的把top命令重定向到一个文件(recordTOP.sh),另一个脚本就是一个if判断大小(checksize.sh)。再加上crontab每一天一检查(其实完全没必要,500MB足够top这个命令跑5天的),应该可以满足开发人员的需求。
脚本内容
获取top.txt
的脚本recordTOP.sh
如下:
1
2
3
4
5
6
7
8
9
10
#written by ChenShuo @2016-8-15
#Desription:每一秒钟记录一次top命令里占用cpu前五程序
while true
do
$(top -bn 1 | head -12 >> /root/top.txt)
echo "------------------------------------------------" >> /root/top.txt
sleep 1
done
判断top.txt
大小的脚本checksize.sh
如下:
1
2
3
4
5
6
7
8
9
10
#written by ChenShuo @2016-8-15
#Desription:当recordTOP.sh文件大小超过500MB的时候将会重新覆盖
size=$(ls -l | grep top.txt |cut -d " " -f 5)
if [[ $size -ge 536870912 ]]
then
$(ps -ef|grep recordTOP.sh|grep -v grep|awk '{print $2}'|xargs kill -9)
$(rm -rf /root/top.txt)
bash /root/recordTOP.sh &
fi
crontab
这一步我就略掉不写了。
补充说明
1)top不可以直接重定向,如果是top > 123.txt
,它将会不断的导入,因为top就是一个实时更新的命令,所以这里要用top -bn 1|head 12 >> /top.txt
;
2)shell脚本里调用shell,不能采用$()
的方法了,因为$()
是一个返回值,而.sh是一个不断进行的脚本,所以要用bash +脚本名
的方式;
3)recordTOP.sh这个脚本是可以同时存在多个的,但是如果不小心后台启动多个,用checksize脚本ps -ef语句就会报错,因为获得到的不是一个数字,而是多个数字,没法一波kill掉。同理,直接调用checksize也会报错,因为没有ps -ef的值;
4)因为是要先关闭原来的top重定向脚本,所以才用了保守的ps -ef,然后kill的方式,这里不可以使用pkill,因为pkill是干掉整个类型程序,比如pkill -9 java
,就是干掉所有java的进程。而在linux里,千万不可以pkill -9 sh
,可以想象一下,这个命令的结果就是会从ssh上跳出,同时无法登陆,因为整个sh都被你杀死了。那么真的出现了这个结果怎么办?答曰:重启,重启能救命。
整个执行效果如下,可见top.txt文件是在不断的扩大,由于是测试,我把文件大小调整为20000字节,即大于20000字节就覆盖原文件,当文件大于20000字节的时候,就会把原来的top.txt删除,同时生成一个新的top.txt。