Use mkdir as an Atomic Lock in a Cron Shell Script
Use mkdir as a lock because it either creates the directory or fails, in one atomic step. It keeps a second copy of a cron job from starting, with no flock needed.
A job started by cron must not run twice at the same time, and flock is not available on every system.
try() {
if mkdir job.lock 2> /dev/null; then
echo "$1: got the lock"
sleep 1
rmdir job.lock
echo "$1: released it"
else
echo "$1: busy, skipping"
fi
}
try first &
sleep 0.2
try second
wait
try third
mkdir job.lock
mkdir job.lock
echo "exit status: $?"first: got the lock
second: busy, skipping
first: released it
third: got the lock
third: released it
mkdir: cannot create directory 'job.lock': File exists
exit status: 1Creating a directory is a single operation that fails if the name exists, so only one of two competing scripts wins. The run starts first in the background, and second, tried 0.2 seconds later, printed busy, skipping. After first released the lock with rmdir, third took it. Doing it with test and then touch leaves a gap between the two steps, which mkdir does not have. The call is described in mkdir.
A script killed with kill -9 or by a power cut leaves the directory behind and blocks every later run, so store the PID inside and check it, or remove the lock with a trap on exit. On NFS the guarantee depends on the server. Where flock exists it releases the lock itself when the process dies.