I am using Rsnapshot for backups (Linux CentOS 6).

Here is my /etc/cron.d/rsnapshot:

30 11 * * * root    /usr/bin/rsnapshot nowandthen > /backups/rsnapshot_cron.txt 2>&1
15 11 * * 4 root    /usr/bin/rsnapshot weekly > /backups/rsnapshot_cron.txt 2>&1
00 11 24-31 * 4 root    /usr/bin/rsnapshot monthly > /backups/rsnapshot_cron.txt 2>&1

Monthly backup was intended to be executed every last Thursday in any month.

However, monthly backup executed today, Thursday, 2016-Feb-18 at 11:00. Today is not last Thursday in a month.

What's wrong with my crontab?

  • what do you see in your logs? – Jakuje Feb 18 '16 at 13:04
  • Your crontab appears to be correct. Do you have the correct date on your computer? What's the output of date? Anything relevant in from grep CRON /var/log/syslog? – agtoever Feb 18 '16 at 13:22
  • I can't explain why it ran on 18th, but remember there are several crontab files: as well as /etc entries there is one for each user, including root. Regardless, your script will not do what you want: if the last day of a 31-day month is a Thursday it will run on both 24th and 31st; if the last day of February is a Wednesday it won't run at all. – AFH Feb 18 '16 at 13:42

According to this site, your string means “At 11:00 on the 24, 25, 26, 27, 28, 29, 30 and 31st of every month and every Thu.” (my emphasis). If the site is correct this would explain why it ran on 18th.

The example entry in man 5 crontab to run on 2nd Saturday is:

0 4 8-14 * *    test $(date +\%u) -eq 6 && echo "2nd Saturday"

(ie run every day of the second week and check for the week day as part of the command) - this supports the view that the week day is an additional, alternative filter, not a further qualification, though the manual page does not make it clear.

So in your case I would use:

00 11 * * 4 root test $(date -d @$((`date +\%s`+604800)) +\%m) -ne $(date +\%m) && /usr/bin/rsnapshot monthly > /backups/rsnapshot_cron.txt 2>&1

Check if your date supports -d 'next Thursday': if so you can use the rather simpler:

00 11 * * 4 root test $(date -d 'next Thu' +\%m) -ne $(date +\%m) && /usr/bin/rsnapshot monthly > /backups/rsnapshot_cron.txt 2>&1

This runs every Thursday and checks if the date a week (604800 seconds) from now is in the same month: if not, it must be the last Thursday so the back-up command runs.

  • You will need to escape percent signs, like in the 2nd Saturday example. – tripleee Feb 18 '16 at 20:35
  • If you have GNU date, it supports -d "next thursday" +%m so you can skip one nested subcommand. – tripleee Feb 18 '16 at 20:38
  • @tripleee - I tested the command with bash on Ubuntu, and no escaping was necessary, though I didn't check it in crontab, because testing would be too difficult. I can imagine it would be necessary in a GNU/Windows environment, but I'll change my answer, as it can do no harm. Thanks for the "next Thursday" tip: it works on Ubuntu, so I'll incorporate it. – AFH Feb 18 '16 at 22:49
  • The escaping of percent signs is a requirement which is specific to crontab syntax; so yes, it would work at the prompt without escaping. – tripleee Feb 19 '16 at 5:41
  • No time to test... waiting for the next Thursday. :) – Danijel Feb 19 '16 at 10:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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