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" email@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"