This is an old revision of the document!
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>
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)
- 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}
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}