Unusual cron job settings
cron jobs can be set up to run at various times, such as:
- X minutes past every hour
- Y minutes past hour Z
- X,Y and Z minutes past hours A,B and C
- Every Monday at a particular time
- The Nth day of each month at a particular time
Some cron systems can also be set to run jobs:
- 3 times per hour (at 0, 20 and 40 minutes past)
- 4 times per hour plus an offset (eg: at 3, 18, 33 and 48 minutes past)
However, there are some things that standard cron configurations can't cope with, such as:
- the first Monday of each month
- the last Friday of each month
- the 14th of each month provided it's a Tuesday
Note: It may at first seem simple to set up a job to run on the 14th of the month when it's a Tuesday, but it turns out that if you do specify this, the job runs both every Tuesday and also on the 14th of the month. It's the isolated instance of a logical OR between timings, when all others are a logical AND.
34 12 14 * Tue command.sh
Anyway, back to the topic…
How do you set up a cron job to run on the first Monday of each month?
There are two pretty much equally simple ways of going about this (and probably several others which are not so simple):
- Set up a job to run every Monday, and check whether it's the first one in the month
- Set up a job to run on the first seven days of each month, and check whether the day is a Monday
For example (assuming the job should run at 03:45 on the appropriate day) either of the following will work:
45 3 * * Mon test `date +%e` -lt 8 && command.sh 45 3 1-7 * * test `date +%u` -eq 1 && command.sh
Note that I used "date +%u" to get the numerical day of the week (1=Monday, 7=Sunday) instead of "date +%a" (for Mon, Tue, Wed, etc) to avoid any internationalisation problems - you want the command to work on a machine whose system language is French or German just the same as it works in English.
For the next example…
How do you set up a cron job to run on the last Friday of each month?
This not so simple, because there's no easy way of knowing which dates in a month represent the final seven days.
In this case, we run a check every Friday to find out whether the current month is the same as the month in seven days' time:
45 3 * * Fri test `date +%m` -eq `date +%m -d +7days` || command.sh
So, every Friday, if the month number equals the month number in 7 days' time, we do not run the command, otherwise we do.
How do you set up a cron job to run on every Tuesday when it's the 14th of the month?
By now this should be obvious - use either of:
45 3 * * Tue test `date +%e` -eq 14 && command.sh 45 3 14 * * test `date +%u` -eq 2 && command.sh
Backticks
Some people might change `…` into $(…) - feel free to use this syntax if you prefer it.
Go up
Return to main index.