Cleanup Housekeeping Script

This script uses a configurable search file to scan certain directories for files of a given type and modification time. These files can then be deleted or simply reported as an alerting mechanism that some old files have been lying around for ages.

The key is the search_variables file which can be specified with the -f option or it takes the default path set by the SEARCH_FILE variable. The file is of the format:

#SYNTAX
#TYPE:FILENAME:RETENTION:LOOKIN
core_dump:core:+7:/u01/data1
trace:trace.[0-9]*:+7:/apps/exe
#DBI:DBI[0-9]*:+7:/u01/data1
lbi:lbi[0-9]*:+7:/u01/data1
que:que[0-9]*:+7:/apps/reports
srt:srt[0-9]*:+7:/u02/reports/sort
#pk:*.pk*:+31:/u02/reports/packages

Lines which begin with a # are comments and these lines will not be searched.

The four fields are

If used interactively, the -h option will provide some usage information

bash$ /usr/local/bin/cleanup -h
Usage: /usr/local/bin/cleanup : [ -c | -d | -f /path/to/search/file | -h ]
Where
  -c = check for these files
  -d = find and delete these files
  -f = path to the file containing search strings
  -h = display help text and exit
bash$

With -c the script will check for but not delete the files; with -d the files will be deleted if found. In both cases the report (as a zip file) will be mailed to the $MAILLIST recipients.

The script is best executed as a cron job of the form

20 21 * * 2 /usr/local/bin/cleanup -d -f /usr/local/bin/search_variables 2>&1

Given the -c and -d options, it is possible to have more than one cron job scheduled, e.g. one to delete certain files, the other to search for (but not delete) another file list. For instance:

25 21 * * 2 /usr/local/bin/cleanup -c -f /usr/local/bin/find_these 2>&1

The script is:

#!/usr/bin/ksh
#
# Cleanup script

#set -vx
OUTPUT=/var/tmp/cleanup
MESSAGE=$OUTPUT/cleanup.$$
MAILLIST=sysop@example.co.uk
SUBJECT="`hostname` Disk Space Cleanup"
RM=""
SEARCH_FILE=/usr/local/bin/search_variables
totsize=0
totfiles=0
delete="no"
blank=""
sep="+++++++++++++++++++++++++++++++++++++++++++++++"

get_target()
{
set -A pps $@
file=${pps[0]}
targets=`awk -F: '{print $1}' $file | grep -v "^#"`
return targets
}

read_vars()
{
set -A pps $@
target=${pps[0]}
file=${pps[1]}
if [ x$target = "x" ]
then
    echo "You must enter a target name"
    exit 1
fi
TYPE=`grep "^${target}:" $file | awk -F: '{print $1}'`
FILENAME=`grep "^${target}:" $file | awk -F: '{print $2}'`
RETENTION=`grep "^${target}:" $file | awk -F: '{print $3}'`
LOOKIN=`grep "^${target}:" $file | awk -F: '{print $4}'`
return TYPE FILENAME RETENTION LOOKIN
}

spacer()
{
echo $blank  | tee -a $MESSAGE
echo $sep  | tee -a $MESSAGE
echo $blank | tee -a $MESSAGE
}

exclude_check()
{
set -A pps $@
for x in ${pps[*]}
do
    y=`echo $x | egrep -v "(traf|escrow)"`
    z=`echo $z $y`
done
FINDHERE=$z
return FINDHERE
}

tidyup()
{
cd $OUTPUT
rm *.lst
rm $MESSAGE
rm cleanup.zip
}

usage()
{
cat </dev/null
do
case $r in
    c) RM=""
       delete="no";;
    d) RM="rm -f {}"
       delete="yes";;
    f) SEARCH_FILE=$OPTARG;;
    h|*) usage;;
esac
done

spacer
echo "Disk space cleanup begins at `date`" | tee -a $MESSAGE

echo $blank | tee -a $MESSAGE

get_target $SEARCH_FILE
for type in $targets
do
   echo "Looking for $type files" | tee -a $MESSAGE
   read_vars $type $SEARCH_FILE
   FINDHERE=$LOOKIN
   if [ $delete = "yes" ]
   then
       echo "The following files will be removed using command" >> $OUTPUT/${TYPE}.lst
   else
       echo "Checking for the following files using command" >> $OUTPUT/${TYPE}.lst
   fi
   if [ $TYPE = "d_files" ]
   then
      exclude_check "$FINDHERE"
   fi
   echo "find $FINDHERE -depth -type f -name "$FILENAME" -mtime $RETENTION -ls -exec $RM \; " >> $OUTPUT/${TYPE}.lst
   find $FINDHERE -depth -type f -name "$FILENAME" -mtime $RETENTION -ls -exec $RM \; >> $OUTPUT/${TYPE}.lst
   x=`wc -l $OUTPUT/${TYPE}.lst | awk '{print $1}'`
   numfiles=`expr $x - 2`
   size=`tail +3 $OUTPUT/${TYPE}.lst | awk '{ m += $7 } END { print m }'`
   if [ ! $size ]
   then
       size=0
   fi
   totsize=`expr $totsize + $size`
   totfiles=`expr $totfiles + $numfiles`
   sizemb=`echo $size | awk '{ m += $1 } END { print m/1024/1024 }'`
   echo "There are $numfiles $TYPE files older than $RETENTION days totalling $sizemb Mb" | tee -a $MESSAGE
   echo $blank
done

spacer

if [ $delete = "yes" ]
then
    totsizemb=`echo $totsize | awk '{ m += $1 } END { print m/1024/1024 }'`
    echo "$totfiles files totalling $totsizemb Mb have been removed" | tee -a $MESSAGE
    echo $blank | tee -a $MESSAGE
    echo "cleanup -d ends at `date`" | tee -a $MESSAGE
    spacer
else
    totsizemb=`echo $totsize | awk '{ m += $1 } END { print m/1024/1024 }'`
    echo "$totfiles files totalling $totsizemb Mb have been found" | tee -a $MESSAGE
    echo $blank | tee -a $MESSAGE
    echo "cleanup -c ends at `date`" | tee -a $MESSAGE
    spacer
fi

echo "Mailing results as zip file cleanup.zip ..." | tee -a $MESSAGE
cd $OUTPUT
zip cleanup *.lst

spacer

mailx -s "${SUBJECT}" $MAILLIST << EOF
`cat $MESSAGE`
~< ! uuencode cleanup.zip cleanup.zip 2>/dev/null
EOF

tidyup

exit 0