Skip to content
shellhacks.dev
Automation

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.

1 min read
Summarize in AI

A job started by cron must not run twice at the same time, and flock is not available on every system.

Shell
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: $?"
Text
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: 1

Creating 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.

Share

More snippets

Automation

Wait for a TCP Port to Open in a Bash Script

Wait until a TCP port accepts connections with a Bash loop that opens /dev/tcp/host/port, with no nc needed. It returns 0 once open, or 1 after the tries run out.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.