Cron – Not running a cron job when the prev run was not finished

cron

How can I block a cron job when the previous run was not finished. Its a cron job which is running every 5 minutes, but sometimes it needs more than 5 minutes to run.

Edit
The script which is called, crashes sometimes! So it can not delete lock file.

Best Answer

Use flock(1):

NAME
       flock - manage locks from shell scripts

SYNOPSIS
       flock [options] <file> -c <command>
       flock [options] <directory> -c <command>
       flock [options] <file descriptor number>
[...]

You can have it block or immediately exit. Pre-existence (or absence) of the lock file doesn't make a difference. It creates the file if needed and uses a flock() system call to lock the file. This lock is automatically released at process death.

For example, in cron:

*/5 * * * * /usr/bin/flock /tmp/my.lock /usr/local/bin/myjob

If your jobs don't always finish in 5 minutes, you might consider using --timeout so that your jobs don't queue up:

flock --timeout=300

Or use --nonblock to exit immediately -- it would be similar to --timeout=0

If your script is a shell script, you can use some clever redirection tricks to use flock within your script itself:

(
  flock -n 9 || exit 1
  # ... commands executed under lock ...
) 9>/var/lock/mylockfile            

Or, the manual also suggests making your script recursive by putting this at the top (it uses the script itself as its lock file):

[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :

See the flock(1) man page for more information