Friday, 17 December 2010

Find command

Was dealing with a messy historic script on one of the servers that had 100s find commands and rm `cat file_generated_by_find` so started to look at turning this into a single find cmd which would locate all files older than 90 days in a given dir but exclude certain dirs and certain file globs.

I knocked together this script to allow me to have a list of files globs I wanted to always keep and a list of directories I wanted to exclude from pruning of old files.

#!/bin/bash
#-------------------------------------------------------------------------------
# IMPORTANT VARIABLES THAT MUST BE DEFINED
#-------------------------------------------------------------------------------

# Min age in days of files you don't want deleted
MIN_AGE=90

# Set debug: value of zero/0/blank and files are deleted any other numeric
# value and a printout of the files to be deleted is displayed instead
DEBUG=1

# Configure file globs you never ever want deleted
neverDelete="rbe675* rbe081* rrv708* rrv709* rrv710* rrv112* RBE081*"

# Configure directories you want to completely exclude from old file search
excludeDirs="oracle Archived frb_output fsc_output"

#-------------------------------------------------------------------------------
# Construct params for the find command used in Northgate spool dirs
#-------------------------------------------------------------------------------
# Set up the param for find cmd to exclude dirs in "excludeDirs" list
findParamExcludeDirs='! \('
for d in ${excludeDirs}; do
    findParamExcludeDirs="${findParamExcludeDirs} -name ${d} -type d -prune -o"
done
findParamExcludeDirs=`echo ${findParamExcludeDirs}|sed 's/\-o$/\\\)/'`

# Set up the param for find cmd to ensure files in "neverDelete" list are kept
findParamNoDel='! \( '
for f in ${neverDelete}; do
    findParamNoDel="${findParamNoDel} -name ${f} -o"
done
findParamNoDel=`echo ${findParamNoDel}|sed 's/\-o$/\\\)/'`

# Set find's exec cmd to delete or list files based on value of DEBUG
# So if we have DEBUG>0 then we don't delete files but list them
if [ -z "${DEBUG}" -o "${DEBUG}" -eq 0 ]; then
    # Not in debug mode so set exec cmd to 'rm' to remove files
    execCmd='-exec ls {} \;'
else
    # In debug mode so just list the files you would delete
    echo '** IN DEBUG MODE ** DISPLAYING FILES THAT WOULD BE DELETED'
    execCmd='-exec ls -lh {} \;'
fi

#-------------------------------------------------------------------------------
# Start using find to deleting old file
#-------------------------------------------------------------------------------
# Now loop thro both spool dirs, deleting files > 'n' days old
for spoolDir in '/var/spool/LIVE /var/spool/TEST'; do
    echo "Deleting old files from spool dir ${spoolDir}"
    eval "find ${spoolDir} ${findParamExcludeDirs} -a ${findParamNoDel} -type f -mtime +${MIN_AGE} ${execCmd}"
done

# Clear out /var/tmp
echo "Deleting old temp files..."
eval "find /var/tmp/ -name '*.tmp' -mtime +1 -type f ${execCmd}"

echo "Deleting old oracle trace files..."
eval "find /var/spool/LIVE/oracle/bdump/*.trc -mtime +30 -type f ${execCmd}"
eval "find /var/spool/TEST/oracle/bdump/*.trc -mtime +30 -type f ${execCmd}"

exit
#-------------------------------------------------------------------------------
# END OF SCRIPT TO DELETE OLD FILES
#-------------------------------------------------------------------------------

Its not perfect but it does show you how to construct a find command dynamically.

On a connected note the touch command is useful when testing the find command, it allows us to create files with certain date/time stamps.  e.g. this creates 3 test files

touch -t 200901312359 test1.txt
touch -t 201004152359 test2.txt
touch -t 201008152359 test2.txt
touch -t 201010032359 test3.txt 

You can also change timestamps on wildcards with touch -t 201012250000 test*.txt

No comments: