Sometimes you have to make sure that only one instance of a shell script is running at the same time.
For example a cron job which is executed via crond that does not provide locking on its own (e.g. the default Solaris crond).
A common pattern to implement locking is code like this:
#!/bin/sh LOCK=/var/tmp/mylock if [ -f $LOCK ]; then echo Job is already running\! exit 6 fi touch $LOCK # do some work rm $LOCK
Of course, such code has a race condition. There is a time window where the
execution of two instances can both advance after line 3 before one is able to
For a cron job this is usually not a problem because you have an interval of minutes between two invocations.
But things can go wrong - for example when the lockfile is on a NFS server - that hangs. In that case several cron jobs can block on line 3 and queue up. If the NFS server is active again then you have thundering herd of parallel running jobs.
Searching on the web I found the tool lockrun which seems like a good solution to that problem. With it you run a script that needs locking like this:
$ lockrun --lockfile=/var/tmp/mylock myscript.sh
You can put this in a wrapper or use it from your crontab.
On current Linux systems you probably want to apply following patch to get working locking via NFS:
--- a/lockrun.c Tue Oct 04 20:39:42 2011 +0200 +++ b/lockrun.c Tue Oct 04 20:40:39 2011 +0200 @@ -97,11 +97,7 @@ __attribute__((noreturn)) __attribute__((format(printf, 1, 2))); -#ifdef __sun # define WAIT_AND_LOCK(fd) lockf(fd, F_TLOCK,0) -#else -# define WAIT_AND_LOCK(fd) flock(fd, LOCK_EX | LOCK_NB) -#endif
This should also work on all current UNIX-like systems because lockf is POSIX.
Are there alternatives to lockrun?
What about other cron daemons? Are there common crond's that support locking in a sane way? A quick look into the man page of Vixie Crond (default on Debian/Ubuntu systems) does not show anything about locking.
Would it be a good idea to include a tool like
lockrun into coreutils?
In my opinion it implements a theme very similar to
nice and friends.