1

I have this in my crontab

0 3 * * * mysqldump --host=10.100.100.3 --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)?

user9517
  • 115,471
  • 20
  • 215
  • 297
Alaa Alomari
  • 638
  • 6
  • 19
  • 37

4 Answers4

9

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.

hmontoliu
  • 3,753
  • 3
  • 23
  • 24
4

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 {} \;
Lekensteyn
  • 6,241
  • 6
  • 39
  • 55
2

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

rm -f `find /tmp/mysqldumps -mtime +30 -name mydb.\*.gz`
Phil
  • 3,168
  • 1
  • 22
  • 29
  • 2
    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 04 '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 04 '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 04 '11 at 13:48
0

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: $

mgjk
  • 874
  • 3
  • 9
  • 20
  • 2
    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 04 '11 at 14:06