====== 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/
===== Files That Control Crontab Access =====
* /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 |
----
===== Format of User Crontabs =====
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
----
===== Crontab Examples =====
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.
===== Automation Example =====
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)# .---------------- 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)#!/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}
==== Other Date Check Examples ====
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}
----