Difference between revisions of "Cron Notes"

From Noah.org
Jump to: navigation, search
 
m
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
I have huge, horrible, complex cron files.
+
[[Category:Engineering]]
 +
 
 +
See also [[Bash notes]] for some techniques to prevent multiple cron job from running at the same time. This happens if a cron job has not finished before cron tries to start it again.
 +
 
 +
== run once (runonce, flock) ==
 +
 
 +
Most Linux distros off the '''flock''' utility for scripting. Lock files are normally opened under '''/var/lock''' or '''tmp'''.
 +
 
 +
Note that the '''-c''' option requires exactly one argument so be sure to quote it if your command itself has arguments.
 +
<pre>
 +
if ! flock -n /var/lock/my.lockfile -c 'echo "This is a a test."'; then                                                                 
 +
    echo "ERROR: The lockfile is locked by another process." >&2                                                                         
 +
fi
 +
</pre>
 +
 
 +
Another convention for using '''flock''' inside of scripts is to use the file descriptor style lock.
 +
<pre>
 +
(
 +
    flock -n 9 || exit 1
 +
    # ... commands executed under lock ...
 +
    echo "Holding lock for 5 minutes..."
 +
    sleep 300
 +
) 9>/var/lock/my.lockfile
 +
</pre>
 +
 
 +
You can list locks using '''lsof'''.
 +
 
 +
== Cron documentation comment ==
 +
 
 
I stick this big comment at the top of the /etc/crontab file so  
 
I stick this big comment at the top of the /etc/crontab file so  
 
I don't have to keep going back to the man page.
 
I don't have to keep going back to the man page.
Line 10: Line 38:
 
#    day of month  1-31
 
#    day of month  1-31
 
#    month          1-12 (or names, see below)
 
#    month          1-12 (or names, see below)
#    day of week    0-7 (0 or 7 is Sun, or use names)
+
#    day of week    0-7 (0 and 7 are both Sunday).
# A field may be an asterisk (*), which always stands for ''first-last''.
+
#    The following names may also be used:
 +
#          0 sun, 1 mon, 2 tue, 3 wed, 4 thr, 5 fri, 6 sat, 7 sun
 +
# A field may be an asterisk (*), which stands for "first-last".
 +
# Ranges are two numbers separated with a hyphen.
 +
# Ranges are inclusive. For example, "8-11" for  "hours" specifies
 +
# hours 8, 9, 10 and 11.
 
#  
 
#  
# Ranges of numbers are allowed. Ranges are two numbers separated with a hyphen.
+
# A list is a set of numbers (or ranges) separated by commas.
# The specified range is inclusive. For example, 8-11 for an ''hours'' entry
+
# Examples: "1,2,5,9", "0-4,8-12".
# specifies execution at hours 8, 9, 10 and 11.
+
 
#  
 
#  
# Lists are allowed.  A list is a set of numbers (or ranges) separated by commas.
+
# Step values may be added with a "/" at the end of a range or *
# Examples: ''1,2,5,9'', ''0-4,8-12''.
+
# to specify the number of values to jump to get to the next item.
#
+
# For example, "0-12/2" can be used in the hours field to specify
# Step values can be used in conjunction with ranges. Following a range with
+
# every other hour. This is equivalent to  "0,2,4,6,8,10,12".
# ''/<number>'' specifies  skips of the number's value through the range.  
+
# Note that this includes both Midnight and Noon.
# For example, ''0-23/2'' can be used in the hours field to specify command
+
# If you want to specify "every two hours", use "*/2"
# execution every other hour (the alternative in the V7 standard is
+
# (equivalent to "0,2,4,6,8,10,12,14,16,18,20,22).
# ''0,2,4,6,8,10,12,14,16,18,20,22''). Steps are also permitted after an
+
# Note that the  day of a command's execution can be specified
# asterisk, so if you want to say ''every two hours'', just use ''*/2''.
+
# by both day of month and day of week. If both fields are specified
 +
# (that is, not *), then either field will cause the command to run.
 +
# For example, "30 4 1,15 * 5" would cause a command
 +
# to be run at 4:30 AM on the 1st and 15th of each month,
 +
# plus every Friday (5th day of the week) at 4:30 AM.
 +
#
 +
# The "sixth" field (the rest of the line) specifies the command to be run.
 +
# The entire command portion of the line, up to a newline or %
 +
# character, will be executed by /bin/sh or by the shell specified in the
 +
# SHELL variable of the crontab file. Percent-signs (%) in the command,
 +
# unless escaped with backslash (\), will be changed into newline characters,
 +
# and all data after the first % will be sent to the command as standard input.
 +
# There is no way to split a command over multiple lines,
 +
# similar to the shell's trailing "\".
 
#
 
#
# Example cron file
+
# Example system /etc/crontab:
#      # run five minutes after midnight, every day
+
#      SHELL=/bin/sh
#      5 0 * * *      $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
+
#      PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#      # run at 2:15pm on the first of every month -- output mailed to paul
+
#      MAILTO=""
#      15 14 1 * *    $HOME/bin/monthly
+
#      # Run all scripts in /etc/cron.hourly every hour seventeen minutes after the hour.
#      # run at 10 pm on weekdays, annoy Joe
+
#      17 * * * *  root    cd / && run-parts --report /etc/cron.hourly
#      0 22 * * 1-5    mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
+
#      # run every day seven minutes after midnight
#      23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
+
#      7 0 * * *      root /usr/sbin/ntpdate time.nist.gov >> /var/log/ntpdate.log 2>&1
#      5 4 * * sun    echo "run at 5 after 4 every sunday"
+
#      # run every month on the first at 2:15 PM. Ignore all output (errors and stdout).
 +
#      15 14 1 * *    root /bin/foo >/dev/null 2>&1
 +
#      # run weekdays at 11 PM
 +
#      0 23 * * 1-5    root mail -s "Alert: 11 PM" joe@example.com%Joe,%%Where are your kids?%
 +
#      23 0-23/2 * * * root echo "run every day, 23 minutes after midnight, 2am, 4am..."
 +
#      5 4 * * sun    root echo "run every Sunday at 5 minutes after 4"
 +
#      */5 * * * *    root echo "run every 5 minutes"
 +
#      0 */2 * * *    root echo "run every 2 hours on the hour"
 
</pre>
 
</pre>

Latest revision as of 13:54, 13 August 2015


See also Bash notes for some techniques to prevent multiple cron job from running at the same time. This happens if a cron job has not finished before cron tries to start it again.

run once (runonce, flock)

Most Linux distros off the flock utility for scripting. Lock files are normally opened under /var/lock or tmp.

Note that the -c option requires exactly one argument so be sure to quote it if your command itself has arguments.

if ! flock -n /var/lock/my.lockfile -c 'echo "This is a a test."'; then                                                                  
    echo "ERROR: The lockfile is locked by another process." >&2                                                                           
fi 

Another convention for using flock inside of scripts is to use the file descriptor style lock.

(
    flock -n 9 || exit 1
    # ... commands executed under lock ...
    echo "Holding lock for 5 minutes..."
    sleep 300
 ) 9>/var/lock/my.lockfile

You can list locks using lsof.

Cron documentation comment

I stick this big comment at the top of the /etc/crontab file so I don't have to keep going back to the man page.

# The time and date fields are:
#     field          allowed values
#     -----          --------------
#     minute         0-59
#     hour           0-23
#     day of month   1-31
#     month          1-12 (or names, see below)
#     day of week    0-7 (0 and 7 are both Sunday).
#     The following names may also be used:
#           0 sun, 1 mon, 2 tue, 3 wed, 4 thr, 5 fri, 6 sat, 7 sun
# A field may be an asterisk (*), which stands for "first-last".
# Ranges are two numbers separated with a hyphen.
# Ranges are inclusive. For example, "8-11" for  "hours" specifies
# hours 8, 9, 10 and 11.
# 
# A list is a set of numbers (or ranges) separated by commas.
# Examples: "1,2,5,9", "0-4,8-12".
# 
# Step values may be added with a "/" at the end of a range or * 
# to specify the number of values to jump to get to the next item.
# For example, "0-12/2" can be used in the hours field to specify
# every other hour. This is equivalent to  "0,2,4,6,8,10,12".
# Note that this includes both Midnight and Noon. 
# If you want to specify "every two hours", use "*/2"
# (equivalent to "0,2,4,6,8,10,12,14,16,18,20,22).
# Note that the  day of a command's execution can be specified 
# by both day of month and day of week. If both fields are specified 
# (that is, not *), then either field will cause the command to run.
# For example, "30 4 1,15 * 5" would cause a command 
# to be run at 4:30 AM on the 1st and 15th of each month,
# plus every Friday (5th day of the week) at 4:30 AM.
#
# The "sixth" field (the rest of the line) specifies the command to be run.
# The entire command portion of the line, up to a newline or %
# character, will be executed by /bin/sh or by the shell specified in the
# SHELL variable of the crontab file. Percent-signs (%) in the command,
# unless escaped with backslash (\), will be changed into newline characters, 
# and all data after the first % will be sent to the command as standard input. 
# There is no way to split a command over multiple lines, 
# similar to the shell's trailing "\".
#
# Example system /etc/crontab:
#      SHELL=/bin/sh
#      PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#      MAILTO=""
#      # Run all scripts in /etc/cron.hourly every hour seventeen minutes after the hour.
#      17 * * * *   root    cd / && run-parts --report /etc/cron.hourly
#      # run every day seven minutes after midnight
#      7 0 * * *       root /usr/sbin/ntpdate time.nist.gov >> /var/log/ntpdate.log 2>&1
#      # run every month on the first at 2:15 PM. Ignore all output (errors and stdout).
#      15 14 1 * *     root /bin/foo >/dev/null 2>&1
#      # run weekdays at 11 PM
#      0 23 * * 1-5    root mail -s "Alert: 11 PM" joe@example.com%Joe,%%Where are your kids?%
#      23 0-23/2 * * * root echo "run every day, 23 minutes after midnight, 2am, 4am..."
#      5 4 * * sun     root echo "run every Sunday at 5 minutes after 4"
#      */5 * * * *     root echo "run every 5 minutes"
#      0 */2 * * *    root echo "run every 2 hours on the hour"