[[linux_wiki:cron]]

Cron

General Information

Automating tasks with cron (the daemon that executes scheduled commands).

Checklist

  • Distro(s): Any

User Crontabs

Individual users can create/edit their own cron jobs.


List your user's crontab jobs

crontab -l


Edit your crontab

crontab -e


User crontabs are stored at:

  • /var/spool/cron/<username>
  • /etc/cron.allow
  • /etc/cron.deny

About these files:

  • One username per line
  • Root can always use crontab, regardless of file existence below
cron.allow cron.deny Result
file exists file exists Only users in cron.allow are allowed
no file file exists All users allowed except those in cron.deny
file exists no file Only users in cron.allow are allowed
no file no file Only root is allowed to use crontab

For any below, asterisk means all values.

# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  *  command to be executed

Executes script.sh at 0600,0630,1200,and 1230 every day of the month, every month, and everyday of the week.

0,30 6,12 * * * /home/user/script.sh

Executes script.sh every minute.

* * * * * /home/user/script.sh

Executes script.sh every 5 minutes.

*/5 * * * * /home/user/script.sh

Executes script.sh on system startup.

@reboot /home/user/script.sh

System Cron Jobs

To run jobs in the system directories, look to /etc.

  • /etc/cron.d/ = system executed jobs (format like crontab)
  • /etc/cron.daily/ = daily executed scripts (format bash script)
  • /etc/cron.hourly/ = hourly executed scripts (format bash script)
  • /etc/cron.monthly/ = monthly executed scripts (format bash script)
  • /etc/cron.weekly/ = weekly executed scripts (format bash script)
  • /etc/crontab = system wide crontab

It is recommended to drop scripts into one of the /etc/cron.* directories instead of editing the system wide crontab file.

All formats are bash scripts, except for the /etc/cron.d/ directory, which accepts crontab formatted files, with the addition of specifying a username.

For example, /etc/cron.d/crashplan-mirror:

# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
 
# Rsync the crashplan backups to another usb drive for redundancy
0 2,14 * * * root /root/scripts/rsync_cp_mirror.sh

The above executes at 0200 and 1400, runs as the user root, the script specified.


Cron Keywords

Keywords that can be used in place of a specific time/date schedule.

  • @reboot - Run once at start up.
  • @yearly - Run once a year.
  • @annually - Same as yearly.
  • @monthly - Run once a month.
  • @weekly - Run once a week.
  • @daily - Run once a day.
  • @midnight - Same as daily.
  • @hourly - Run once an hour.

Cron - Relative Days

Cron is great at being specific about minutes, hours, dates, months, and days of the week, but is not able to handle relative days.

  • Relative days could come in handy when you need a job to execute on something such as the 1st, 2nd and 3rd Tuesday of every month.
  • In order to accomplish this, a combination of cron and a date checker script is used.

In this example, we want a script to execute on the 1st, 2nd, and 3rd Tuesday of every month, with different arguments depending upon which Tuesday it is.

  • Cron entry: Execute a date checker script every Tuesday
    • Create the system wide cron entry (/etc/cron.d/automated_jobs)
      cron-automated-jobs
      # .---------------- minute (0 - 59)
      # |  .------------- hour (0 - 23)
      # |  |  .---------- day of month (1 - 31)
      # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
      # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
      # |  |  |  |  |
      # *  *  *  *  *  user-name  command to be executed
       
      #Every Tuesday at 0800: Determine if an automated job should be run
      #-Target: 1st,2nd,3rd Tues of month
      00 08 * * tue  root  /automation/automated-job-check.sh
  • Date checker script: Determine if the actual automated program should run and what arguments to send it.
    • Create the date checker script (/automation/automated-job-check.sh)
      automated-job-check.sh
      #!/bin/bash
      # Title: automated-job-check.sh
      # Description: Determine if an automated job should be run
       
      # Script to execute: See 'if statement' for dynamically selecting an environment
      script="/automation/scripts/automated-job.py"
       
      # Log file
      log_file="/var/log/automation/automated-job-check_$(date +%Y%m).log"
       
      echo "==== Log Started: $(date) ====" >> ${log_file}
       
      # If today is Tuesday AND today is >=1 and <=21(1st,2nd,3rd Tue)
      if [[ "$(date '+%a')" == "Tue" ]] && [[ $(date +%-d) -ge 1 ]]; then
       
        # First Tue: Development Environment
        if [[ $(date +%-d) -le 7 ]]; then
          echo ">> OK: Today is the first Tue of the Month; execute script(${script} --group all_dev)." >> ${log_file}
          ${script} --group all_dev 2>&1 >> ${log_file}
       
        # Second Tue: Test Environment
        elif [[ $(date +%-d) -le 14 ]]; then
          echo ">> OK: Today is the second Tue of the Month; execute script(${script} --group all_test)." >> ${log_file}
          ${script} --group all_test 2>&1 >> ${log_file}
       
        # Third Tue: Production Environment
        elif [[ $(date +%-d) -le 21 ]]; then
          echo ">> OK: Today is the third Tue of the Month; execute script(${script} --group all_prod)." >> ${log_file}
          ${script} --group all_prod 2>&1 >> ${log_file}
       
        else
          echo ">> NO-EXEC: Today is NOT the first,second, or third Tue of the Month. Will NOT execute script(${script})." >> ${log_file}
        fi
      else
        echo ">> NO-EXEC: Today is NOT the first,second, or third Tue of the Month. Will NOT execute script(${script})." >> ${log_file}
      fi
       
      echo -e "==== Log Ended: $(date) ====\n" >> ${log_file}

A few other examples of date checker scripts with relative days before/after.


7 Days before the first Tuesday of the month

#!/bin/bash
# Title: automated-job-check.sh
# Description: Determine if an automated job should be run
 
# Script to execute:
script="/automation/scripts/automated-job.py"
 
# Log file
log_file="/var/log/automation/automated-job-check_$(date +%Y%m).log"
 
echo "==== Log Started: $(date) ====" >> ${log_file}
 
# If today is Tuesday AND 7 days from now is >=1 and <=7(first Tue)
if [[ "$(date '+%a')" == "Tue" ]] && [[ $(date +%-d -d "+7 days") -ge 1 ]]; then
  if [[ $(date +%-d -d "+7 days") -le 7 ]]; then
    echo ">> OK: Seven days from now is the first Tue of the Month; execute script(${script})." >> ${log_file}
    ${script} 2>&1 >> ${log_file}
  else
    echo ">> NO-EXEC: Seven days from now is NOT the first Tue of the Month. Will NOT execute script(${script})." >> ${log_file}
  fi
else
  echo ">> NO-EXEC: Seven days from now is NOT the first Tue of the Month. Will NOT execute script(${script})." >> ${log_file}
fi
 
echo -e "==== Log Ended: $(date) ====\n" >> ${log_file}


2 Days after the third Tuesday of the month

#!/bin/bash
# Title: automated-job-check.sh
# Description: Determine if an automated job should be run
 
# Script to execute
script="/automation/scripts/automated-job.py"
 
# Log file
log_file="/var/log/automation/automated-job-check_$(date +%Y%m).log"
 
echo "==== Log Started: $(date) ====" >> ${log_file}
 
# If today is Thursday AND two days ago was >=15 and <=21(third Tue)
if [[ "$(date '+%a')" == "Thu" ]] && [[ $(date +%-d -d "-2 days") -ge 15 ]]; then
  if [[ $(date +%-d -d "-2 days") -le 21 ]]; then
    echo ">> OK: Two days ago was the third Tue of the Month; execute script(${script})." >> ${log_file}
    ${script} 2>&1 >> ${log_file}
  else
    echo ">> NO-EXEC: Two days ago was NOT the third Tue of the Month. Will NOT execute script(${script})." >> ${log_file}
  fi
else
  echo ">> NO-EXEC: Two days ago was NOT the third Tue of the Month. Will NOT execute script(${script})." >> ${log_file}
fi
 
echo -e "==== Log Ended: $(date) ====\n" >> ${log_file}

  • linux_wiki/cron.txt
  • Last modified: 2019/05/26 03:50
  • (external edit)