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...

Tags:

Cron

Debian