Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have this in my crontab

0 3 * * * mysqldump --host= --user=username --password=mypass --routines DBName | gzip > /tmp/mysqldumps/mydb.`date +"\%Y-\%m-\%d"`.gz

now I need to create another cron job to do this scenario assuming we are in 3rd of May 2011 I want to remove the file that has been created one month ago ie. rm mydb.2011-04-03.gz

Any idea of how to generate this cron job (how to generate the name of the file to be deleted)?

share|improve this question
up vote 7 down vote accepted

You have serveral options; I propose two of them:

Remove the file by date (each day the destination dir will be searched for files older than one month and the matches will be deleted):

10 3 * * * find /tmp/mysqldumps/ -maxdepth 1 -ctime +30 -exec rm {} \;

Remove the file by name:

10 3 * * * rm /tmp/mysqldumps/mydb.`date -d "last month" +'%Y-%m-%d.gz'`

I prefer the former one because is more robust. Also if the remove cron job for some reason one day doesn't run, the next day the former command will do the trick. In my second example the file wont be deleted.

share|improve this answer

Instead of parsing the file name, you can also check the modification time of a file.

The next command looks in the /tmp/mysqldumps directory. Filenames starting with mydb. and ending on .gz, older than 30 days are removed.

find /tmp/mysqldumps -name 'mydb.*.gz' -mtime +30 -exec rm {} \;
share|improve this answer

You can remove files older than e.g. 30 days using a command like

rm -f `find /tmp/mysqldumps -mtime +30 -name mydb.\*.gz`
share|improve this answer
Not safe enough, if the path contains spaces (not in this case), the behavior is unexpected. You'd better use the -exec option. – Lekensteyn May 4 '11 at 12:59
Also (probably not the case) it's always better to run commands inside find (whith -exec) rather than from the output of find as you proposed. In your command if find gets more results than ARG_MAX you rm wont work. I know that is rather improbable, but It happened to me more than twice :-) – hmontoliu May 4 '11 at 13:11
Use xargs: find /tmp/mysqldumps -mtime +30 -name 'mydb.*.gz' -print0|xargs -0 -n 50 rm -f .... That will delimit names with a null, which xargs will pick, and the -n 50 specifies no more than 50 on the line, so no problems with overrunning command line buffer. – lsd May 4 '11 at 13:48

For cron jobs any more complex than your example, I like to put the cron jobs in scripts under ~/cron/, then I can comment them as to who wrote them, why they're there and when they were installed.

One way to do the math on your date would be like this. I wouldn't incorporate this into a one-liner, although I'm sure it's possible with multiple escapes and stuff:

printf "%d-%02d-%02d" `date +%Y` $((`date +%m`-1))  `date +%d`

(serverfault swallowed my backticks... I think I got them to show)

IMHO, find is better for removing files. Look for files which match your pattern older than the date. It's safer and doesn't leave things around in extended power downs.

It might even look clean in a one-liner... I'll dig around for an example.

Aha, here's an example where the files "noooo" and "omg" get clobbered because of something in the ./findtest/ directory:

$ ls -R
findtest  noooooo  omg

./findtest: mydb- file is * mydb-old-file.gz $ rm `find ./findtest/ -name mydb*` rm: cannot remove `./findtest/mydb-': No such file or directory rm: cannot remove `file': No such file or directory rm: cannot remove `is': No such file or directory rm: cannot remove `findtest': Is a directory $ ls -R .: findtest

./findtest: mydb- file is *

Good way:

$ find ./findtest/ -name mydb* -exec rm {} \;
$ ls -R
findtest  noooooo  omg

./findtest: $

share|improve this answer
If you have gnu date (and possible others), you can do date -d 'last month' +'%Y-%m-%d', which will do the same thing as your printf (at the top) with less processes and more robust. Subtract 1 from month 1, January, and you get 0, which will result in 2011-00-04, which is not valid. Letting date to it for you will give you the correct results. – lsd May 4 '11 at 14:06

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.