log_rotater.sh
#!/bin/sh
# Writed by yijian on 2012/7/22
# 本腳本功能:
# 1) 實現一個通用的按大小的日志滾動
# 2) 要求日志文件擴展名為“.log”,否則請稍修改代碼
# 3) 支持處理多個目錄下的日志文件,如果需要使用這個功能,
# 必須啟用dirs_list參數
#
# 為何要寫一個這樣的東東?
# 答:因為在日常中,經常發現程序輸出重定向,
# 或腳本的輸出,如果不處理的話,就可能導致
# 單個文件過大,甚至爆滿整個磁盤;而每套腳本
# 都重復寫一個日志滾動邏輯,顯然是件無聊的事,
# 甚至一些人懶得做處理,日子一久,就會發現一個超大的
# 日志文件,本腳本希望可以幫助解決這個問題,讓大家無
# 後顧之憂。
#
# 使用方法:
# 1) 把腳本復制到日志文件所在目錄,
# 然後以nohup ./log_rotater.sh > /dev/null & 等方式啟動腳本即可
# 2) 除了上面的方法,也可以將log_rotater.sh任何目錄下,
# 但這個時候,應當將backup_dir的值修改為日志文件所在目錄
#
# sudo dpkg-reconfigure dash
# 新版本Ubuntu默認使用dash作為shell,
# 這個shell功能較弱,不支持數組等,但速度快,
# 可采取如下辦法檢測是何種shell:
# ls -l `which sh`
# 可根據需要修改以下參數
backup_count=10 # 日志滾動的個數
backup_size=$((1024 * 1024 * 200)) # 單個日志文件大小
backup_interval=60 # 檢測的間隔時間,單位為秒
# 如果dirs_list指定的文件存在,則從dirs_list中讀取目錄,
# 否則僅處理backup_dir指定的單個目錄
# 往dirs_list指定文件增減目錄時,不需要重啟log_rotater.sh
backup_dir=. # 日志文件所在目錄
dirs_list=./dirs.list # 存儲目錄列表的文件,要求一行一個目錄
# 處理單個目錄下的日志滾動
scan_single_dir()
{
dir=$1
cd $dir
if test $? -ne 0; then
return
fi
# 用到了awk給外部變量賦值的特性
eval $(ls -l --time-style=long-iso *.log 2>/dev/null|awk '{ printf("filesize=%s\nfiledate=%s\nfilename=%s\n", $5,$6,$8); }')
if test $? -ne 0; then
return
fi
if test -z $filename; then
return
fi
if test $filesize -gt $backup_size; then
file_index=$(($backup_count - 1))
while test $file_index -gt 1; do
new_filename="${filename}.$file_index"
old_filename="${filename}.$(($file_index - 1))"
if test -f "$old_filename"; then
mv "$old_filename" "$new_filename"
fi
file_index=$(($file_index - 1))
done
# 這裡需要使用truncate,而不能使用mv,
# 因為需要保持文件的inode不變
cp "$filename" "${filename}.1"
truncate -s 1024 "$filename"
fi
cd -
sleep 1
}
# 循環檢測
while true; do
if test ! -f $dirs_list; then
scan_single_dir $backup_dir
else
while read dirpath
do
scan_single_dir $dirpath
done < $dirs_list
fi
sleep $backup_interval
done
本文出自 “飛月” 博客,請務必保留此出處http://mooon.blog.51cto.com/1246491/941086