shell指令碼自動清理超過指定大小的檔案

worfs123456發表於2016-12-07

轉載自: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 好啊。

後續的引申可以再將次腳步稍微整理下,加上簡單的清理日誌記錄,同時掛上計劃任務,這樣就可以自動去清理了。同時類似的,以後類似的需求,

均可以由此指令碼簡單修改而實現。


相關文章