shell的一个不错的定期清理脚本

来源:互联网 发布:阿里云开通码 编辑:程序博客网 时间:2024/05/19 02:21

最近写了一个删除脚本,用于定期删除某些文件夹中的数据,该脚本需要如下参数:
①设置删除的目录
②该目录最少保留的时间,如3天
③该目录最多保留的时间,如30天
④该目录最大空间大小,如10G
⑤该目录所在磁盘分区的最大使用量,如80%
以上三个条件只要满足其中一条,便开始删除目录中30天前的数据,然后检查,若仍然满足,则继续删除29天前的数据,如此循环,直至磁盘分区使用量小于80%
改进:刚开始使用的是exit,但是这有个问题就是,如果要定期清理多个目录,就无法满足需求了,因为检查了第一个目录整个脚本就exit退出,而用return就ok,只会退出当前函数,会继续检查下一个目录
以下是脚本内容:粗略测试了一下,没什么问题,欢迎大家一起测试

最近做了个改版的,取消设置目录最大大小,触发条件仅为分区使用量,因为设置最大目录大小感觉很鸡肋

#!/bin/bash:<<block    author:@michaelzeng    date:2016-04-27blockloglevel=0 #debug:0; info:1; warn:2; error:3logdir=/data/logs/diskchklogfile=${logdir}/diskchk.logtest -d $logdir || mkdir -p $logdirfunction log {    local msg;local logtype        logtype=$1        msg=$2        datetime=`date +'%F %H:%M:%S'`        logformat="[${logtype}]\t${datetime}\tfuncname: ${FUNCNAME[@]/log/} [line:`caller 0 | awk '{print$1}'`]\t${msg}"        {        case $logtype in                debug)                        [[ $loglevel -le 0 ]] && echo -e "\033[30m${logformat}\033[0m" ;;                info)                        [[ $loglevel -le 1 ]] && echo -e "\033[32m${logformat}\033[0m" ;;                warn)                        [[ $loglevel -le 2 ]] && echo -e "\033[33m${logformat}\033[0m" ;;                error)                        [[ $loglevel -le 3 ]] && echo -e "\033[31m${logformat}\033[0m" ;;        esac        } >> $logfile        #} | tee -a $logfile}function check(){    #检查目录,确保目录不在以下目录,以免被误删    notdeldir='/ /boot /boot/ /var /var/ /lib/ /lib /etc /etc/ /bin /bin/ /lib64  /lib64/ /usr/ /usr  /apps /apps/ /boot_ucloud /boot_ucloud/ /data /data/ /dev /dev/ /home /home/ /lost+found /lost+found/ /media /media/ /mnt /mnt/ /opt /opt/ /proc /proc/ /root /root/ /sbin /sbin/ /selinux /selinux/ /srv /srv/'    local src_dir=$1    for blackdir in $notdeldir;    do        if [[ $src_dir == $blackdir ]];then            log error "$src_dir:can't delete this directory"            return 10        fi    done    return 0}function chkuse(){    local src_dir=$1    local partition;local par_size;local disk_ppc    partition=`df -Ph $src_dir|awk '/dev/{print $6}'`    par_size=`df -Ph $src_dir|awk '/dev/{print $2}'|tr -d G`    disk_ppc=`df -Ph $src_dir|awk '/dev/{print $5}'|tr -d %`    if [ ${disk_ppc} -le ${use} ]; then        log info "partition:$partition; use:${disk_ppc}%,$src_dir dir is ok"        return 1    else        log info "partition:$partition; use:${disk_ppc}%,we will clean dir:$src_dir"        return 0    fi}function clean(){       #满足删除条件时,删除文件直到分区用量小于$use    paracount=3    if [ $# -eq $paracount ]; then        local src_dir=$1        local min_tmd=$2        local max_tmd=$3    else        return 1    fi    local disk_ppc=0    #目录所在分区,分区大小,分区已用量    chkuse $src_dir    if [ $? -eq 1 ]; then        #log debug "disk:$partition; use:${disk_ppc}%,no need to clean"        return 4    else        local delfile        delfile=$(find ${src_dir} -type f -mtime +${max_tmd})        if [[ -n $delfile ]];then            log debug "delete file ${max_tmd} days ago;in dir:$src_dir;delete file : $delfile"            for file in $delfile;do rm -f $file;done            #for file in $delfile;do echo $file;done        fi    fi}# MIN_TMD 保留最短时间(天为单位)# MAX_TMD 保留最长时间(天为单位)function do_clean(){    PARACOUNT=3    if [ $# -eq $PARACOUNT ]; then        local SRC_DIR=$1        local MIN_TMD=$2        local MAX_TMD=$3    else        echo "Usage: ${FUNCNAME[@]} <SRC_DIR> <MIN_TMD> <MAX_TMD>"        log debug "need $PARACOUNT parameters,but give:$#"        return 1    fi    if [ ${MAX_TMD} -lt ${MIN_TMD} ]; then        log debug "para MAX_TMD should be biger than MIN_TMD"        return 2    fi    if [ ! -d "$SRC_DIR" ];then        log debug "$SRC_DIR: No such directory"        return 3    fi    check $SRC_DIR    if [ $? -eq 0 ];then        #删除大于$MAX_TMD天的文件        local delfile        delfile=$(find ${SRC_DIR} -type f -mtime +${MAX_TMD})        if [[ -n $delfile ]];then            log debug "delete file that ${MAX_TMD} days ago,in dir:$SRC_DIR,file:${delfile}"            for file in $delfile;do rm -f $file;done            #for file in $delfile;do echo $file;done        fi        #开始循环检查        chkuse ${SRC_DIR}        if [[ $? -eq 0 ]];then            ((TM=MAX_TMD))            COUNT=$(( MAX_TMD-MIN_TMD ))            for(( i=0; i<=COUNT;i++ ))            do                clean "$SRC_DIR" "$MIN_TMD" "$TM"                if [ $? -eq 4 ]; then                    break                fi                if [ ${TM} -gt ${MIN_TMD} ]; then                    (( TM=TM-1 ))                else                    #达到最少保留天数限制,则找出大于8G的大文件,清空                    log warn "still not enough space,we will find the big file and clean it"                    bigfile=$(find ${SRC_DIR} -type f -size +${max_filesize})                    if [[ -n $bigfile ]];then                        log debug "clean the filesize -gt ${max_filesize},bigfile is $bigfile"                        for f in $bigfile;do echo '' > $f;done                        chkuse ${SRC_DIR}                        break                    fi                fi            done        fi    fi}##################  main  ####################举个栗子:/var/spool/clientmqueue/目录,最少保留3天,最多保留30天use=75 #定义某分区最大使用量max_filesize=8G #定义最大文件大小,当达到最少保留天数限制时,清空该文件#do_clean /var/spool/clientmqueue/ 3 10do_clean /data/logs/ 3 10do_clean /data/backup/ 3 10

最初版本:

#!/bin/bash:<<block    author:@michaelzeng    date:2016-04-27blockuse=30 #定义某分区最大使用量loglevel=0 #debug:0; info:1; warn:2; error:3logfile=${0%.*}".log"function log {        local msg;local logtype        logtype=$1        msg=$2        datetime=`date +'%F %H:%M:%S'`        #logformat="[${logtype}]\t${datetime}\tfuncname:${FUNCNAME[@]}\t[line:$LINENO]\t${msg}"        logformat="[${logtype}]\t${datetime}\tfuncname: ${FUNCNAME[@]/log/} [line:`caller 0 | awk '{print$1}'`]\t${msg}"        {        case $logtype in                debug)                        [[ $loglevel -le 0 ]] && echo -e "\033[30m${logformat}\033[0m" $logflag;;                info)                        [[ $loglevel -le 1 ]] && echo -e "\033[32m${logformat}\033[0m" $logflag;;                warn)                        [[ $loglevel -le 2 ]] && echo -e "\033[33m${logformat}\033[0m" $logflag;;                error)                        [[ $loglevel -le 3 ]] && echo -e "\033[31m${logformat}\033[0m" $logflag;;        esac        #} >> $logfile        } | tee -a $logfile}function check(){    #检查目录,确保目录不在以下目录,以免被误删    notdeldir='/ /boot /boot/ /var /var/ /lib/ /lib /etc /etc/ /bin /bin/ /lib64  /lib64/ /usr/ /usr  /apps /apps/ /boot_ucloud /boot_ucloud/ /data /data/ /dev /dev/ /home /home/ /lost+found /lost+found/ /media /media/ /mnt /mnt/ /opt /opt/ /proc /proc/ /root /root/ /sbin /sbin/ /selinux /selinux/ /srv /srv/'    local src_dir=$1    for blackdir in $notdeldir;    do        if [[ $src_dir == $blackdir ]];then            log error "$src_dir:can't delete this directory"            return 10        fi    done    return 0}function clean(){       #满足删除条件时,删除文件直到分区用量小于$use    paracount=4    if [ $# -eq $paracount ]; then        local src_dir=$1        local min_tmd=$2        local max_tmd=$3        local max_dsk=$4    else        return 1    fi    local disk_ppc=0    #目录所在分区,分区大小,分区已用量    partition=`df -Ph $src_dir|awk '/dev/{print $6}'`    par_size=`df -Ph $src_dir|awk '/dev/{print $2}'|tr -d G`    disk_ppc=`df -Ph $src_dir|awk '/dev/{print $5}'|tr -d %`    if [ ${disk_ppc} -le ${use} ]; then        log debug "disk:$partition; use:${disk_ppc}%,no need to clean"        return 4    fi    #检查设置的目录最大大小是否小于分区的$use%    max_use=$((par_size*use/100))    if [ $max_dsk -gt $max_use ];then        #echo "目录最大使用量设置错误,需小于所在分区大小的${use}%"        #max_dsk改为分区大小的${use}%        log warn "parameter MAX_GB:$max_dsk > ${par_size}*${use}/100,set default:par_size*use/100"        max_dsk=$max_use    fi    #目录大小    local src_dir_sz=`du --summarize --block-size=1G ${src_dir} | awk '{print $1}'`    if [ ${src_dir_sz} -gt ${max_dsk} ]; then        #找出${src_dir}中${max_tmd}天前以日期命名的目录并删除直到,${src_dir}空间大小小于${max_dsk}         local delfile        delfile=$(find ${src_dir} -type f -mtime +${max_tmd} | egrep "`date +%Y`")        log debug "in dir:$src_dir;delete file : $delfile"        #find ${src_dir} -type f -mtime +${max_tmd} | egrep "`date +%Y`" |xargs -i rm -f {}    else        return 5    fi}# MIN_TMD 保留最短时间(天为单位)# MAX_TMD 保留最长时间(天为单位)# MAX_GB 目录最多存储空间(GB为单位)# 清理数据按1小时清理直到空间小于MAX_GBfunction do_clean(){    PARACOUNT=4    if [ $# -eq $PARACOUNT ]; then        local SRC_DIR=$1        local MIN_TMD=$2        local MAX_TMD=$3        local MAX_GB=$4    else        echo "Usage: ${FUNCNAME[@]} <SRC_DIR> <MIN_TMD> <MAX_TMD> <MAX_GB>"        log debug "need $PARACOUNT parameters,but give:$#"        return 1    fi    if [ ${MAX_TMD} -lt ${MIN_TMD} ]; then        log debug "para MAX_TMD should be biger than MIN_TMD"        return 2    fi    if [ ! -d "$SRC_DIR" ];then        log debug "$SRC_DIR: No such directory"        return 3    fi    check $SRC_DIR    if [ $? -eq 0 ];then        #删除大于$MAX_TMD天的文件        local delfile        delfile=$(find ${SRC_DIR} -type f -mtime +${MAX_TMD} | egrep "`date +%Y`")        [[ -n $delfile ]] && log info "delete file that ${MAX_TMD} days ago,in dir:$SRC_DIR,file:${delfile}"        #开始循环检查        (( TM=MAX_TMD ))        for(( i=0; i<MAX_TMD; i++ ))        do            if [ ${TM} -gt ${MIN_TMD} ]; then                (( TM=TM-1 ))            else                break            fi            log info "check dir:${SRC_DIR} that ${TM} days ago"            clean "$SRC_DIR" "$MIN_TMD" "$TM" "$MAX_GB"            if [ $? -eq 5 ]; then                break            fi        done    fi}##################  main  ####################举个栗子:/var/spool/clientmqueue/目录,最少保留3天,最多保留30天,最大1Gdo_clean /var/spool/clientmqueue/ 3 30 1do_clean /media 3 30 1 #禁止删除do_clean /media/ 3 30 1 #禁止删除#最大目录大小10G大于分区大小的最大使用量30%do_clean /media/CentOS 3 30 10 do_clean #参数错误
0 0
原创粉丝点击