Contact
Site: US UK AU |
Nexcess Blog

Cron Job For the Last Day of the Month

May 9, 2013 8 Comments RSS Feed

Cron Job For the Last Day of the Month

I think cron is a wonderful creation. It is simple in what it does while being extremely useful. Allow me to present a short introduction to it for those unfamiliar, then I will show you a handy trick you may need someday.

Brief Introduction to Cron

You can set any command to run at any time (or repeatedly at a set interval) by using cron. The name comes from “chronos” – the Greek word for time. If you have Linux, you’re going to have cron. Run the command “crontab” to edit or create the jobs for your user.

The syntax seems a little cryptic at first, but it is very straightforward. You enter a series of numbers and symbols followed by the command you wish to run. The numbers and symbols state the desired time and day to run the command. They are separated by a space as follows:

minute hour day month day-of-week

So this entry:

5 13 * 3 * execute_this

will run the command “execute_this” at 1:05 pm every day in March only. Changing it slightly:

5 13 * 3-5 * execute_this

will run the same command at the same time but now it will run every day in March, April, and May.

As I said, this was a short introduction to cron. If you don’t know what you’re doing here, you may not want to go testing on any important machine. Go research and play around (it’s the best way to learn).

Setting a Cron Job For the Last Day of the Month

So, how do you make a cron job to run on the last day of the month? To get us started, here’s how it would look to run on the first of each month (at 1:05 pm again):

5 13 1 * * execute_this

That “1” in there means when the date is “1”, which is the first day of the month. The problem is we don’t have a number to put there which means the last day of the month. It could be 30, 31, 28, or sometimes even 29. But one thing is always true about the last day of the month, tomorrow is the first! Let’s use that information to create this entry:

59 23 28-31 * * execute_this

I’ve made this one run just before the day was over (11:59 pm) but it could be any time you need. And it will run on each of our possible end of the month dates (28-31), every month.

Obviously, we don’t want our code to execute on October 28. That’s not the last day of the month. The date should be 31 if it’s October, but more importantly (and more reliably) tomorrow’s date should be 1. It’s time to pull out our shell scripting superpowers.

date +%d

will give you the current date as a two character string. But since we want to see what tomorrow is, we ask for that instead

date +%d -d tomorrow

If that matches “01” then we know tomorrow is the first so today must be the last.

[ "$(date +%d -d tomorrow)" = "01" ] && execute_this

Our test (the square brackets) will result in either true or false. It will run that test AND (&&) the next command which is the command we set out to run in the first place. But due to the way computers operate, if the test comes back false, it won’t bother running the second command.

So only when that test comes back as true will it run our second command. This is exactly what we wanted and we have just tricked the computer into doing our evil work. Congratulations!

Here is what we enter in crontab to have our command run at the very end of each month:

59 23 28-31 * * [ "$(date +%d -d tomorrow)" = "01" ] && execute_this

Hosting with great support

Posted in: Linux, Nexcess
  • Manoj Namdev

    Awesome

  • Sobit

    Great!

  • I had to escape the % to get the crontab to work as I was getting errors, but otherwise saved me a ton of time.

  • Mohamed Ennahdi El Idrissi

    Thank you!

  • Mohamed Ennahdi El Idrissi

    Your contribution was useful. Thanks!
    I am using Ubuntu.

  • I have the same problem, so my final command is:
    0 18 28-31 * * root [ $(date +%d -d tomorrow) = 01 ] && my-command
    and work flawlessly. please update the post and thank you very much!

  • Wahyu Rohman Sidik

    what root min in root[…. ??

  • I’m editing directly in /etc/crontab
    so this “root” is the user I like to use to run the command.