$RodHat_
Syscall reference · File descriptors

flock(2)

Apply or remove an advisory whole-file lock tied to an open file description.

Since
4.2BSD; Linux 2.0check your kernel →
glibc
unknown
System
Linux
Man page
flock(2)

Synopsis

#include <sys/file.h>

int flock(int fd, int op);

Rod's take

The pidfile you were about to write is broken three ways: test-and-set races, a SIGKILL leaves it stale forever, and PIDs get recycled. flock(2) is one kernel operation on an open file description, so when the holder dies, however it dies, the lock goes with it. Wrap the cron job in flock -n and an overlapping run just exits. Lock the contested resource, not the job, and share the lock file across every script that touches it. It's advisory: anything that doesn't ask walks straight through. Across hosts or NFS, use something built for distributed locking, not a file and a prayer.

Flags and arguments that matter

NameWhat it does
LOCK_SHShared lock; many processes can hold one at the same time.
LOCK_EXExclusive lock; only one holder at a time.
LOCK_UNRelease the lock held via this open file description.
LOCK_NBOR in to fail with EWOULDBLOCK instead of blocking when the lock is held.

Errors you will actually hit

errnoMeaning
EWOULDBLOCKThe file is locked and LOCK_NB was given.
EINTRA caught signal interrupted the wait for the lock.
EBADFfd is not an open file descriptor.
EINVALop is invalid.
ENOLCKThe kernel ran out of memory for lock records.

Example

# crontab: skip this run if the last one is still going
# */5 * * * * /usr/bin/flock -n /var/lock/report.lock /usr/local/bin/report.sh

#!/bin/bash
# self-locking script: fd 9 holds the lock until the script exits
exec 9>/var/lock/job.lock
flock -n 9 || { echo "already running"; exit 0; }
# ... work ...

# wait up to 60s instead of skipping
flock -w 60 /var/lock/job.lock /usr/local/bin/job.sh

Trimmed from the full walkthrough in Your cron job is running twice and that's why the numbers are wrong.

BSD equivalent

FreeBSD: flock(2) (appeared in 4.2BSD). OpenBSD: flock(2) (first appeared in 4.1cBSD per its man page). On the modern BSDs flock and fcntl locks interact; on Linux they don't (except over NFS/SMB).

The long version, from the console

Sources

  1. flock(2), man7.org
  2. flock(1), man7.org
  3. flock(2), FreeBSD
  4. flock(2), OpenBSD

Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.