Cron allowed special character "L" for "Last day of the month" on Debian
Cron entries on Debian are described in the crontab man page (man 5 crontab
). Debian uses Vixie's cron, and his man page says:
The crontab syntax does not make it possible to define all possible
periods one could image off. For example, it is not straightforward to
define the last weekday of a month. If a task needs to be run in a spe-
cific period of time that cannot be defined in the crontab syntaxs the
best approach would be to have the program itself check the date and
time information and continue execution only if the period matches the
desired one.
If the program itself cannot do the checks then a wrapper script would
be required. Useful tools that could be used for date analysis are ncal
or calendar For example, to run a program the last Saturday of every
month you could use the following wrapper code:
0 4 * * Sat [ "$(date +%e)" = "`ncal | grep $(date +%a | sed -e 's/.$//')
| sed -e 's/^.*\s\([0-9]\+\)\s*$/\1/'`" ] && echo "Last Saturday" &&
program_to_run
So working along those lines:
0 0 * * * perl -MTime::Local -e
'exit 1 if (((localtime(time()+60*60*24))[3]) < 2);' || program_to_run
I've never seen that L
on a Linux cron implementation.
To run a job on the last day of the month, run it on a superset of the actual days and check the date of the next day. With GNU date
, you can use date -d tomorrow
to display the next day's date, so check if it's still in the same month. To avoid trouble in a few locations on a day when daylight savings time starts or end, specify a time of day that isn't the wee hours of the morning (12:00/noon in the examples). Remember that %
is special in a crontab and needs to be protected by a backslash.
42 1 28-31 * * if [ "$(date -d 'today 12:00' +\%m)" != "$(date -d 'tomorrow 12:00' +\%m)" ]; then last_day_of_month_job; fi
You can apply the same technique for the last occurrence of a particular day of the week in the month. Run the job weekly and have it trigger only if the next occurrence would be in a different month.
42 1 * * 3 if [ "$(date -d 'today 12:00' +\%m)" != "$(date -d 'now + 7 days 12:00' +\%m)" ]; then last_wednesday_of_month_job; fi
Kind of awkward to check this experimentally I guess, since that would require changing your clock.
Debian uses the vixie cron implementation, which is referred to in the wikipedia article. The format for crontab expressions is explained in man 5 crontab
, which is a little tricky, since man crontab
is not the same thing (default section 1 is the command crontab
, section 5 is for the format of "crontab" files).
It doesn't mention 'L'.
WRT the alternatives from S.O., the checked answer is the easiest to follow, and does not require an external script, etc. OTOH, it does have a leap year issue...