1

I'm trying to write a script to create mysqldumps daily in a directory as well as check all the backups in that directory and remove any older than 7 days that is going to run on cron.

So my functions work correctly, it's just my last echo command that is not doing what I want it to. This is what I have so far:

DBNAME=database
DATE=`date +\%Y-\%m-\%d_\%H\%M`
SQLFILE=$DBNAME-${DATE}.sql
curr_dir=$1

#MAIN
mysqldump -u root -ppassword --databases $DBNAME > $SQLFILE

echo "$SQLFILE has been successfully created."

#Remove files older than 7 days

for filepath in "$curr_dir"*
    do
        find "$filepath" -mtime +7 -type f -delete
        echo "$filepath has been deleted."
    done
exit

So the backup creations and removal of old files both work. But, my problem is that echo "$filepath has been deleted." is printing all files in the directory instead of just the files older than 7 days that were deleted. Where am I going wrong here?

EDIT (Full solution):

This is the full solution that wound up working for me using everyone's advice from the answers and comments. This works for cron jobs. I had to specify the main function's output filepath because the files were being created in the root directory instead of the path specified in Argument $1.

Thank you everyone for the help! The if statement also checks whether or not $1 is the specified directory I want files to be deleted in.

#Variables
DBNAME=database
DATE=`date +\%Y-\%m-\%d_\%H\%M`
SQLFILE=$DBNAME-${DATE}.sql
curr_dir=$1

#MAIN
mysqldump -u root -ppassword --databases $DBNAME > /path/to/db-backups/directory/$SQLFILE

echo "$SQLFILE has been successfully created."

#Remove files older than 7 days

for filepath in "$curr_dir"*
    do
        if [[ $1 = "/path/to/db-backups/directory" ]]; then
            find "$filepath" -mtime +7 -type f -delete -exec sh -c 'printf "%s has been deleted.\n" "$@"' _ {} +
        fi
    done
exit
d.r.v.
  • 117
  • 1
  • 1
  • 8
  • 2
    I don't know bash, but it looks like your `FOR` loop is saying "If the filepath is older than 7 days, then delete it, and then regardless of whether the file is deleted, say `$filepath has been deleted`" You may consider adding some kind of "if" block or something to limit the echo piece, as well. – phroureo Sep 19 '17 at 20:19
  • 2
    One way to do what @phroureo correctly suggests is to add `-exec echo '{}' "has been deleted" \;` to the `find` command instead of putting it on a separate line. – Mad Physicist Sep 19 '17 at 20:22
  • @phroureo, the bash code doesn't *know* if an individual deletion was successful -- that's all internal to `find`. – Charles Duffy Sep 19 '17 at 20:54
  • 1
    I'd strongly recommend adding some sanity-checking to `$1` -- at the very least, make sure it was specified, otherwise someone's likely to forget it (or run the script without realizing it needed to be specified), and purge everything older than 7 days from whatever the current directory happens to be. – Gordon Davisson Sep 19 '17 at 23:25
  • @GordonDavisson I took heed of your advice. Nearly learned that the hard way, but what I did was add an if statement in my for loop to only delete files if $1 equates to the directory where the backups are in. `for filepath in "$curr_dir"* do if [[ $1 = "/path/to/mysqldump/backups" ]]; then find "$filepath" -mtime +7 -type f -delete -exec echo '{}' "has been deleted." \; fi done exit` – d.r.v. Sep 20 '17 at 16:14

1 Answers1

2

You can merge the echo into the find:

find "$filepath" -mtime +7 -type f -delete -exec echo '{}' "has been deleted." \;

The -delete option is just a shortcut for -exec rm '{}' \; and all the -exec commands are run in the sequence you specify them in.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • 1
    `-exec sh -c 'printf "%s has been deleted.\n" "$@"' _ {} +` is a bit more efficient, running the smallest possible number of external processes (vs one `/bin/echo` per match). – Charles Duffy Sep 19 '17 at 20:50