Notes on Cron for *nix. Cron schedules a job that runs regularly and checks to run every minute. Crontab edits the cron schedules.

crontab [-u user] [file]  { -e | -r | -l }
-e = edit current crontab
-l = list, view crontab
-r = remove

List all cron jobs

crontab -l

Edit cron jobs

crontab -e

Crontab file format and syntax

env vars

http://www.modrails.com/documentation/Users%20guide%20Apache.html#about_environment_variables

Edit crontab and add env var at the top

$ crontab -e

Example of env var in crontab

# Environment variable definitions
FOO=bar
APXS2=/usr/sbin/apxs2

# **WRONG!** You cannot refer to existing variables with the `$` syntax!
PATH=/usr/bin:$PATH

# **WRONG!** You cannot use the 'export' keyword!
export PATH=/usr/bin:/usr/local/bin

# Correct:
PATH=/usr/bin:/usr/local/bin

# Jobs:
# m h  dom mon dow   command
  * *  *   *   *     frobnicator

Time format

<min 0-59> <hour 0-23> <day 1-31> <month 1-12> <dow 0-7> <Command To Execute>
#Min (0-59)  Hour (0-23) Day (1-31) Month (1-12) Day of week (0-7, 0,7=Sunday)

0   18  *   *   *   /home/dakim/bin/backup
#runs "backup" at 18:00 (6pm) every day

SPECIAL characters, keywords

`*` is wildcard, any value
`JAN-DEC` can be used instead of `(1-12)`
`MON-SUN` can be used instead of `(0-7)`

Run every minute

*   *   *   *   *

Run every hour (i.e. 1:00, 2:00, 3:00 – 24:00)

0   *   *   *   *  

Run every hour (i.e. 1:15, 2:15, 3:15, …24:15)

15  *   *   *   *

Run at 5am, 6am, 7am every Monday

0   5,6,7   *   *   1
0   5,6,7   *   *   mon

Run every hour from 9am-5pm from Mon-Fri

0   9-17    *   *   1-5
0   9-17    *   *   mon-fri

Run every Nth time, using START/STEP

#run every 15 minutes, starting from min 0
0/15    *   *   *   *

Run at nth day of the month using DAY-OF-WEEK#N, N=1-5

#run at 9am on the 3rd Sunday
0   9   *   *   0#3

Time is based on local time

cat /etc/timezone

Special string

@reboot
@yearly (or @annually)
@monthly    (same as 0 0 1 * * )
@weekly     (same as 0 0 * * 0)
@daily  (runs on midnight)
@hourly 
@every_minute
@every_second

crontab Tools (online crontab editor/generator)

Common tasks, and examples

Examples from https://orchestrate.io/blog/2014/03/31/cron-in-production-that-is-a-double-edged-sword/

 Stop email

     0 * * * * /command/to/run > /dev/null 2>&1 || true

 did it run?
 Solution: Touch a file and alert on the file’s age.

     0 * * * * /command/to/run && date > /var/run/last_successful_run

 When combined with the above issue, the command should look like this:

     0 * * * * ( /command/to/run && date > /var/run/last_successful_run ) > /dev/null 2>&1 || true

 When did THAT happen?

 Sometimes its prudent to redirect the output of the program into a file. This is useful for capturing the errors, or other such events. The problem is that this usually is paired with the inability to establish when something happened. Seeing a stack trace in the log doesn’t tell you much. For readability its often desirable to attach a time stamp to each line. Luckily you can accomplish this with bash fairly easily.

 Solution: Use a shell wrapper to attach timestamps.
 0 * * * * /command/to/run | while read line ; do echo `date` "$line" ; done > /path/to/the/log

 When combined with the above issues, the command should look like this:
 15 * * * * ( flock -w 0 200 && sleep `perl -e 'print int(rand(60))'` && nice /command/to/run && date > /var/run/last_successful_run ) 2>&1 200> /var/run/cron_job_lock | while read line ; echo `date` "$line" ; done > /path/to/the/log || true

Another easy way to run script in cron is to use cron_helper.sh

15 * * * * /usr/local/bin/cron_helper -c -n job_name -i -s -t /command/to/run

Example

starter.sh script

#!/bin/sh

if [ $(ps aux | grep node | grep -v grep | wc -l | tr -s "\n") -eq 0 ]
then
    export PATH=/usr/local/bin:$PATH
    export NODE_ENV=production
    NODE_ENV=production forever start --sourceDir /var/www index.js >> /var/log/nodelog.txt 2>&1
fi

Change permission and edit crontab

sudo chmod +x /var/www/starter.sh
sudo crontab -e

Add this line to crontab

@reboot /var/www/starter.sh

Example https://www.simonholywell.com/post/2017/01/email-when-file-changes/

in crontab

*   *   *   *   *    cd /var/www; /usr/bin/sha512sum --status -c cron_sums.txt && echo "Success" > /dev/null || echo "Failed" | mail -s "File hashes didn't match" example@example.co.zw

cron on Mac

  • cron was deprecated since OSX 10.4. It still works, though.
  • Use launchd instead

manpage for cron table format

man 5 crontab
  • On Mac Lion +, must set EDITOR to vim before editing crontab. It’s set to vi, and it doesn’t work. Also VISUAL should also be set to vim.
  • If using MacVim, use mvim instead of vim.

In shell configuration, export these env vars.

export EDITOR=vim
export VISUAL=vim

When creating crontab for the first time, you may need to be root to set permission https://superuser.com/questions/201172/mac-crontab-is-never-created

sudo su -
crontab -u <username> -e

verify

crontab -u <username> -l

Once saved, you can return as normal user, and verify it

crontab -l

Alternative to cron

at command

execute something once at certain time/day

$ at 1 pm today
echo "don't forget meeting" | mail you
CTRL-D
;mails this message to myself at 1pm today

execute this shell script on this Friday 6 am

$ at -f myscript.bat 6 am Friday

starts a command at midnight

echo start_backup.sh | at midnight

SaaS solution

https://healthchecks.io/

  • cron monitoring
  • open-source
  • free for 20 cron checks

Other commercial vendors similar to cron

References