Clean up directories recursively with SCOUR shell script

#!/bin/sh
#
# Deletes old data files.
#
# Recursively deletes files older than a specified number of days from a
# specified set of directories.  The directories, retention time in days,
# and an optional shell filename pattern appear, separated by tab characters
# one directory per line, in a configuration file named on the command line.
#
# If no files have been written under a directory since the last time scour was
# run, it will skip deleting old files and log an error message instead.
#
# WARNING: scour follows symbolic links, so don't put symbolic links to
# directories you don't want scoured under data directories.

PATH=/bin:/usr/bin
CONFFILE=/home/dblogs/bin/scour.conf                    # default, if no args
VERBOSEFLAG=
DEBUGFLAG=
ERRS=
LOGGER=echo
TZ=UTC0 export TZ

while [ "$1" != "" ]
do
        case "$1" in
        -v)
                VERBOSEFLAG=1
                ;;
        -x)
                DEBUGFLAG=1
                ;;
        -l)                                             # logs to syslogd
                LOGGER="logger -t `basename $0` -p local0.notice"
                ;;
        -*)
                $LOGGER "unrecognized flag ($1)"
                ERRS=1
                ;;
        *)
                if [ $# -ne 1 ]
                then
                        $LOGGER "only 1 conf file argument permitted"
                        ERRS=1
                fi
                CONFFILE=$1
                ;;
        esac
        shift
done

if [ "$ERRS" != "" ]
then
        $LOGGER "usage: `basename $0` [-l] [-v] [-x] [config-file]"
        exit 1
fi

if [ "$VERBOSEFLAG" != "" ]
then
        $LOGGER "Starting Up"
fi

while read dir age pattern; do
    if [ x$dir = x ]    # ignore blank lines
    then
        continue
    fi

    case $dir in
      #*)              # ignore comments
        continue
        ;;
      *)
        if [ x$pattern = x ]
        then
                pattern="*"
        fi

        # handle ~user expansion for home directory of user
        rdir=`echo echo $dir | csh -f`
        if [ $? != 0 ]; then
            $LOGGER "directory $dir does not exist, skipping"
            continue
        fi

        # expand symbolic link, since find doesn't follow symbolic links
        edir=`cd $rdir && /bin/pwd`
        if [ $? != 0 ]; then
            $LOGGER "directory $dir does not exist, skipping"
            continue
        fi

        if [ "$DEBUGFLAG" != "" ]
        then
            echo "dir=$dir age=$age pattern=$pattern edir=$edir"
        fi

        # if either "$edir/.scour$pattern" doesn't exist yet OR
        #           there are files newer than "$edir/.scour$pattern"
        # then
        #     delete old files and create "$edir/.scour$pattern"
        # else
        #     skip deletions and log message

        if  [ ! -f "$edir/.scour$pattern" ] ||
            (cd $edir; find . -newer "$edir/.scour$pattern" -print) | grep -s .
        then
            # find has a non-intuitive interpretation of age, subtract 1
            FINDAGE=`echo $age 1 - p|dc`
            if [ "$VERBOSEFLAG" != "" ]
            then
                    BEFORE=`du -s $edir|sed 's/^ *([0-9]*).*/1/'`
            fi
            (cd $edir;
             find . -mtime +$FINDAGE -name "$pattern" -exec rm -f {} ;)
             && touch "$edir/.scour$pattern"
            if [ "$VERBOSEFLAG" != "" ]
            then
                AFTER=`du -s $edir|sed 's/^ *([0-9]*).*/1/'`
                # set DELETED to max(0, BEFORE - AFTER)
                DELETED=`echo $BEFORE $AFTER|
                         sed 's/([0-9]*) ([0-9]*).*/b=1;a=2;d=0;if(a<b)d=b-a;d/'|
                             bc`
                $LOGGER "$DELETED blocks from $edir/$pattern ( > $age days old)"
            fi
        else
            $LOGGER "skipping, no recent files in $edir/$pattern"
        fi
        ;;
    esac
done < $CONFFILE

if [ "$VERBOSEFLAG" != "" ]
then
        $LOGGER exiting ...
fi


Example scour.conf file
/data/app/logs/app_inact/LOGS   7       app_act_log.[0-9]*
/data/app/logs/app_inact/LOGS   30      app_act_log.[0-9]*.gpg
/data/app/logs/app_prod1/LOGS   7       app_prod_log.[0-9]*
/data/app/logs/app_prod1/LOGS   30      app_prod_log.[0-9]*.gpg
/data/app/logs/app_web/LOGS     7       app_web_log.[0-9]*
/data/app/logs/app_web/LOGS     30      app_web_log.[0-9]*.gpg


No comments: