shell脚本自动清理超过指定大小的文件

转载自:http://www.furion.info/14.html


先说下背景:我们线上用的squid,根据经验值如果长时间运行则缓存目录下的swap.state会慢慢变大,一旦超过60M,squid的性能就会急剧下降,因此需要定时去清理大于60M的swap.state文件。

由此引出需求,查找cache目录下的所有大于60M的swap.state文件并清除,即:

1.查找cache目录下的所有swap.state文件

2.判断是否大于60M

3.大于60M则清空

相关squid配置如下:

cache_dir coss /data/cache1/coss 120000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100

cache_dir aufs /data/cache1 30000 128 128 min-size=1000000

cache_dir coss /data/cache2/coss 180000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100

cache_dir aufs /data/cache2 50000 128 128 min-size=1000000

cache_dir coss /data/cache3/coss 200000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100

cache_dir aufs /data/cache3 50000 128 128 min-size=1000000

cache_dir coss /data/cache4/coss 200000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100

cache_dir aufs /data/cache4 50000 128 128 min-size=1000000

cache_dir coss /data/cache5/coss 200000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100

cache_dir aufs /data/cache5 50000 128 128 min-size=1000000

cache_dir coss /data/cache6/coss 200000 max-size=1000000 block-size=4096 membufs=100 overwrite-percent=100

这里稍微说下,由于我们配置了coss,所有swap.state主要是在coss目录下,同时我们采用了多进程squid,因此coss目录下存在squid1-squid6等目录。

第一想到的则是常用的du -sh命令: du -sh /data/cache*/coss/squid*/swap.state ,输入如下:

[root@CRN-JZ-2-36X ~]# du -sh /data/cache*/coss/squid*/swap.state 2.7M /data/cache1/coss/squid1/swap.state

270k /data/cache1/coss/squid2/swap.state

2.7M /data/cache1/coss/squid3/swap.state

2.7M /data/cache1/coss/squid4/swap.state

53M /data/cache1/coss/squid5/swap.state

35M /data/cache1/coss/squid6/swap.state

5.6M /data/cache2/coss/squid3/swap.state

4.6M /data/cache2/coss/squid4/swap.state

122M /data/cache2/coss/squid5/swap.state

4.4M /data/cache3/coss/squid4/swap.state

97M /data/cache3/coss/squid5/swap.state

75M /data/cache3/coss/squid6/swap.state

5.4M /data/cache4/coss/squid1/swap.state

74M /data/cache4/coss/squid6/swap.state

可以发现,/data/cache4/coss/squid6/swap.state 等大于60M的swap.state为我们需要清理的目标。

当时就很自然的采用如下方案去实现:

du -sh /data/cache*/coss/squid*/swap.state | awk ‘ { print $1 } ‘  | awk -F’M’ ‘ { print $1 } ‘

思路如下:使用du -sh 查找大于swap.state的大小,同时使用awk 过滤第一个字段,接着为了过滤掉M、只保留数字,再次使用awk 制定”M”作为分界符过滤出文件大小。

输入如下:

270k

2.7

2.7

53

35

5.6

4.6

122

4.4

97

75

5.4

74

可以看出du -sh这种方案的缺点,du -sh 的 输入会自动转换单位,K、M、G,只过滤M会导致部分文件大小无法正常获取,例如第一个的270k。同时使用了多个管道较为繁琐,

且管道过滤之后的只有文件大小,相对应的文件名丢失,后续的处理较麻烦,当然也可以使用数组等解决。故放弃此方案。

问了个朋友有没有好点的方法去处理,他提示我说不要使用带单位的输出,直接ls -l 的输出就可以作为相应的数据源。ls -l输出的结果以字节为单位,简单,容易处理。

这里同时考虑到第一个方案的缺点,因此加了两个临时变量去存储相应的文件名、文件大小。附上最后的方案:

ls -l /data/cache*/coss/squid*/swap.state | while read i;  do size=`echo $i | awk ‘ { print $5 }’`; file=`echo $i | awk ‘ { print $9 }’`;  if [ $size -gt 61865984 ] ; then echo >$file ; fi;done
61865984 字节换成成M单位为60M,这里判断是否大于60M,大于则使用echo 语句将对应文件置空。
   将单行shell整理成可读性较强的脚本:

#! /bin/bash

ls -l /data/cache*/coss/squid*/swap.state | while read i;

do

size=`echo $i | awk ‘ { print $5 }’`; file=`echo $i | awk ‘ { print $9 }’`;

#here the 61865984 byte is equal to 60M

if [ $size -gt 61865984 ] ;

then

echo $file; echo $size

#clean it

echo >$file

fi

done

好吧,其实这篇博客最主要的内容就是我犯了个很傻很天真的错误,采用du -sh这种带自动单位换成的命令去处理,麻烦多多。有时候还是简单的ls 好啊。

后续的引申可以再将次脚步稍微整理下,加上简单的清理日志记录,同时挂上计划任务,这样就可以自动去清理了。同时类似的,以后类似的需求,

均可以由此脚本简单修改而实现。


你可能感兴趣的:(shell)