No, 31 means 31.
However, you can do some trickery. Set the job to run on any day which could potentially be the last day of the month (ie 28-31 in the day-of-month field), and then replace your command with a shell expression comprising a test on the date guarding the command:
0 0 28-31 * * [ "`date +%m`" != "`date --date=tomorrow +%m`" ] && command
The expression inside the test brackets just asks if the month number today is different to the month number tomorrow, which of course will only be true on the last day of the month. Note that the form of this expression depends on your local date
- you may need to tweak it if you don't have the current GNU version.
I should say that I didn't invent this - I found it with a quick Google in a mailing list post by a Matthew Jarvis. I would imagine this is very much a standard old Unix wizard's trick, though.
Here's what I did, and it seems to work in this situation. At least, it shows me an error, whereas running from the command line as the user doesn't show the error.
Step 1: I put this line temporarily in the user's crontab:
* * * * * /usr/bin/env > /home/username/tmp/cron-env
then took it out once the file was written.
Step 2: Made myself a little run-as-cron bash script containing:
#!/bin/bash
/usr/bin/env -i $(cat /home/username/tmp/cron-env) "$@"
So then, as the user in question, I was able to
run-as-cron /the/problematic/script --with arguments --and parameters
This solution could obviously be expanded to make use of sudo or such for more flexibility.
Hope this helps others.
Best Answer
It's not possible to do this with cron alone. You will have to run your application every day and have it decide if today is a the last working day of a month or not and take appropriate action.