How To Run Cronjob Script On The Last Day Of a Month

How to execute script on the last day of a month on Linux or Unix bash shell? How do I run a disk usage or custom reporting shell/perl/python script on the last day of a month on a Linux or Unix-like systems?

You need to use the date command to find out whether tomorrow is the first day of the next month. If it is true, you can run your script.

ADVERTISEMENTS

Say hello to TZ variable

[donotprint]
Tutorial details
Difficulty Easy (rss)
Root privileges No
Requirements Bash/KSH/ZSH
Time 5m
[/donotprint] TZ is time zone environment variable on Linux or Unix-like systems. The TZ environment variable tells functions such as the ctime(3) family and programs like date what the time zone and daylight saving rule is. For example, Greenwich Mean Time can be defined as follows:

TZ='GMT'

You can set TZ as follows to get tomorrow from the current date (+%d):
TZ=GMT-24 date +%d

How do I find out tomorrow date?

The syntax is as follows:

# CDT
TZ=CDT-24 date +%d
 
#PST
TZ=PST-24 date +%d
 
#EDT
TZ=PST-24 date +%d
 
 
#IST
TZ=IST-24 date +%d

Example: Shell script

#!/bin/bash
# Purpose: Tell if it is last day of a month
# Author: Vivek Gite <www.cyberciti.biz> under GPL v2.x+
# ---------------------------------
 
# Find tomorrow day in IST time zone 
day=$(TZ=IST-24 date +%d)
 
# Compare it
# If both are 1 means today is the last day of a month
if test $day -eq 1; then
   echo "Last Day of a Month"
else
   echo "Noop"  
fi

Run it as follows:
$ date
$ ./script

Sample outputs:

Fri Jul 31 12:35:16 IST 2015
Last Day of a Month

Try one more time:
$ date
$ ./script

Tue Aug  4 01:04:48 IST 2015
Noop

Create a wrapper script

Let us say you want to find out disk usage on the last day of a month. You’ve a script called /root/scripts/disk-usage.sh. Modify above script as follows:

#!/bin/bash
# Script: /root/scripts/is-end-of-month.sh
# Purpose: Tell if it is last day of a month
# Author: Vivek Gite <www.cyberciti.biz> under GPL v2.x+
# ---------------------------------
 
# Find tomorrow day in IST time zone 
day=$(TZ=IST-24 date +%d)
 
# Compare it
# If both are 1 means today is the last day of a month
if test $day -eq 1; then
    # Call disk usage script
    /root/scripts/disk-usage.sh
fi

Create a cron job

You can install your cronjob by running the following command:
# crontab -e
Append the following code to run a script called /root/scripts/is-end-of-month.sh once a day:

@daily	       /root/scripts/disk-usage.sh

OR

0 0 * * *      /root/scripts/disk-usage.sh

Save and close the file.

This entry is 14 of 16 in the Linux Cron Jobs Howto & Tutorial series. Keep reading the rest of the series:
  1. What is cron on a Linux or Unix-like systems?
  2. How To Add Jobs To cron Under Linux or UNIX?
  3. Verify crond Daemon And Cronjobs Are Running
  4. Start Restart and Stop The Cron or Crond Service
  5. List / Display All Cron Jobs
  6. Linux / UNIX Crontab File Location
  7. Change Crontab Email Settings ( MAILTO )
  8. Disable The Mail Alert By Crontab Command On a Linux or Unix-like Systems
  9. At What Time Cron Entries In cron.daily, cron.weekly, cron.monthly Run?
  10. Execute Cron Job After System Reboot
  11. Setup and Run PHP Script As A Cron Job
  12. Run crontab job every minute on a Linux or Unix-like system
  13. Running crontab (cron jobs) Every 10 Minutes
  14. Cron Job Script Execution on the Last Day of a Month
  15. Execute / Run crontab (cron jobs) every 1 minute
  16. Ubuntu create cron.log file
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04

ADVERTISEMENTS
7 comments… add one
  • Pádraig Brady Aug 3, 2015 @ 20:50

    It seems unusual to hard code the timezone in the script. Should that be set (already) system wide? Also how robust is this around day light savings time boundaries?
    Taking the example from http://www.pixelbeat.org/cmdline.html#dates an alternative is:

        [ $(date -d '12:00 today +1 day' +%d) = '01' ] || exit
  • Ian Blackwell Aug 4, 2015 @ 0:34

    Or use this version of the date command to return tomorrows date number value.
    date --date=tomorrow +%d

  • Matthew Lenz Aug 4, 2015 @ 3:19

    ## Have to escape the % sign for direct crontab entry.
    ## Run job on the first minute of the last day of the month. Otherwise exit.
    ## Starts trying for last day on the 28th (to deal with Feb).

    0 0 28,29,30,31 * * [ $(date +\%d -d tomorrow) = “01” ] &&

    • Matthew Lenz Aug 4, 2015 @ 3:20

      It cut off the part after the && because i used less than/greater than.

      0 0 28,29,30,31 * * [ $(date +\%d -d tomorrow) = “01” ] && command_you_want_to_run

  • john Aug 4, 2015 @ 5:48

    This is wrong solution. Or wrong title. The cronjob is being run every day, not the last one :)

  • Said Akkas Aug 4, 2015 @ 14:11

    How about evaluating whether tomorrow’s date as day of the month is less than today’s value.

    For bash:

    (("$(date +%d -d tomorrow)" < "$(date +%d)")) && echo 1

    Comparison above will print "1" if today is the last day of the month.

    You can replace echo 1 with path to your script.

  • Philippe Petrinko Aug 5, 2015 @ 19:26

    Nevertheless,
    here is another way to get last month of current month.

    Following code is simple, robust because it does not rely on any timezone.

    I already gave it on this site in a similar topic:


    # this will compute the last day of current month.
    date -d "+1 month - $(date +%d) days"

    __Philippe

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.