Difference between revisions of "Cron Notes"

From Noah.org
Jump to navigationJump to search
m
 
(7 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
# Ranges of numbers are allowed. Ranges are two numbers separated with a hyphen.
+
# A field may be an asterisk (*), which stands for "first-last".
# The specified range is inclusive. For example, 8-11 for an "hours" entry
+
# Ranges are two numbers separated with a hyphen.
# specifies execution at hours 8, 9, 10 and 11.
+
# Ranges are inclusive. For example, "8-11" for "hours" specifies
 +
# hours 8, 9, 10 and 11.
 
#  
 
#  
# Lists are allowed.  A list is a set of numbers (or ranges) separated by commas.
+
# A list is a set of numbers (or ranges) separated by commas.
 
# Examples: "1,2,5,9", "0-4,8-12".
 
# Examples: "1,2,5,9", "0-4,8-12".
 
#  
 
#  
# Step values can be used in conjunction with ranges. Following a range with
+
# Step values may be added with a "/" at the end of a range or *
# "/<number>" specifies  skips of the number's value through the range.  
+
# to specify the number of values to jump to get to the next item.
# For example, "0-23/2" can be used in the hours field to specify command
+
# For example, "0-12/2" can be used in the hours field to specify
# execution every other hour (the alternative in the V7 standard is
+
# every other hour. This is equivalent to  "0,2,4,6,8,10,12".
# "0,2,4,6,8,10,12,14,16,18,20,22"). Steps are also permitted after an
+
# Note that this includes both Midnight and Noon.
# asterisk, so if you want to say "every two hours", just use "*/2".
+
# If you want to specify "every two hours", use "*/2"
# Note:  The day of a command's execution can be specified by two fields
+
# (equivalent to "0,2,4,6,8,10,12,14,16,18,20,22).
# -- day of month, and day of week. If both fields are restricted
+
# Note that the day of a command's execution can be specified  
# (that is, are not *), the command will be run when either field matches the
+
# by both day of month and day of week. If both fields are specified
# current time.  For example, "30 4 1,15 * 5" would cause a command  
+
# (that is, not *), then either field will cause the command to run.
# to be run at 4:30 am on the 1st and 15th of each month, plus every Friday.
+
# 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
+
# The "sixth" field (the rest of the line) specifies the command to be run.
# run. The entire command portion of the line, up to a newline or %
+
# 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
 
# 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,
 
# SHELL variable of the crontab file. Percent-signs (%) in the command,
 
# unless escaped with backslash (\), will be changed into newline characters,  
 
# 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.  
 
# and all data after the first % will be sent to the command as standard input.  
# There is no way to split a single command line onto multiple lines,  
+
# There is no way to split a command over multiple lines,  
# ala the shell's trailing "\".
+
# similar to the shell's trailing "\".
 
#
 
#
# Example system /etc/crontab excerpt:
+
# Example system /etc/crontab:
#      # run five minutes after midnight, every day
+
#      SHELL=/bin/sh
#      5 0 * * *      root /usr/sbin/ntpdate time.nist.gov >> /var/log/ntpdate.log 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
+
#      MAILTO=""
#      15 14 1 * *    root /bin/foo > /dev/null 2>&1
+
#      # Run all scripts in /etc/cron.hourly every hour seventeen minutes after the hour.
#      # run at 11 pm on weekdays
+
#      17 * * * *  root    cd / && run-parts --report /etc/cron.hourly
#      0 23 * * 1-5    root mail -s "It's 11pm" joe%Joe,%%Where are your kids?%
+
#      # run every day seven minutes after midnight
#      23 0-23/2 * * * root 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    root 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 14: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"