What's wrong with my bash script to keep last x files and delete the rest?
I have this bash script which nicely backs up my database on a cron schedule:
#!/bin/sh
PT_MYSQLDUMPPATH=/usr/bin
PT_HOMEPATH=/home/philosop
PT_TOOLPATH=$PT_HOMEPATH/philosophy-tools
PT_MYSQLBACKUPPATH=$PT_TOOLPATH/mysql-backups
PT_MYSQLUSER=*********
PT_MYSQLPASSWORD="********"
PT_MYSQLDATABASE=*********
PT_BACKUPDATETIME=`date +%s`
PT_BACKUPFILENAME=mysqlbackup_$PT_BACKUPDATETIME.sql.gz
PT_FILESTOKEEP=14
$PT_MYSQLDUMPPATH/mysqldump -u$PT_MYSQLUSER -p$PT_MYSQLPASSWORD --opt $PT_MYSQLDATABASE | gzip -c > $PT_MYSQLBACKUPPATH/$PT_BACKUPFILENAME
Problem with this is that it will keep dumping the backups in the folder and not clean up old files. This is where the variable PT_FILESTOKEEP
comes in. Whatever number this is set to thats the amount of backups I want to keep. All backups are time stamped so by ordering them by name DESC will give you the latest first.
Can anyone please help me with the rest of the BASH script to add the clean up of files? My knowledge of bash is lacking and I'm unable to piece together the code to do the rest.
Solution 1:
First, be sure you are in right folder:
if [ -z $PT_MYSQLBACKUPPATH ]; then
echo "No PT_MYSQLBACKUPPATH set. Exit"
exit 1
fi
cd $PT_MYSQLBACKUPPATH
if [ $? != 0 ]; then
echo "cd to PT_MYSQLBACKUPPATH failed. Exit"
exit 1
fi
You can remove files older than n, in your case:
find -mtime +14 -delete
Deletes files older than 14 days.
More complicated (definitely not optimal, though) solution for your question:
# Get list of newest files. If newest files are first, use head -n 14 instead of
# head.
files=(`ls | sort | tail -n 14`)
# Loop over all files in this folder
for i in *; do
preserve=0;
#Check whether this file is in files array:
for a in ${files[@]}; do
if [ $i == $a ]; then
preserve=1;
fi;
done;
# If it wasn't, delete it (or in this case, print filename)
if [ $preserve == 0 ]; then
echo $i; # test first, then change this to "rm $i"
fi;
done
Solution 2:
You could try this one:
ls -r1 $PT_MYSQLBACKUPPATH/ | tail -n +$(($PT_FILESTOKEEP+1)) | xargs rm
ls -r1
will list all files in reverse order, one file per line.
tail -n +$number
filters the first $number-1 files of the list out (resp. displays all files beginning from $number till the last one).
xargs
will execute rm
with all file names from standard input.