The lockf command is a small but useful Unix utility for applying advisory file locks from the shell. It is commonly used in scripts to prevent multiple instances of a process from running at the same time.
What lockf does
lockf applies a POSIX advisory lock on an open file descriptor. As long as the process holds the lock, other processes attempting to acquire a conflicting lock will either block or fail, depending on how lockf is invoked.
This is most often used for:
- Preventing concurrent cron jobs
- Serializing access to shared resources
- Implementing simple process-level mutexes in shell scripts
The locking is advisory, meaning all cooperating processes must also use locking for it to be effective.
Basic usage
The most common pattern is wrapping a command:
lockf /var/lock/myjob.lock my_command
This:
- Opens (and creates if needed) the lock file
- Acquires an exclusive lock
- Executes
my_command - Releases the lock when the command exits
Non-blocking locks
To fail immediately if the lock is already held, use -n:
lockf -n /var/lock/myjob.lock my_command || exit 0
This is ideal for cron jobs where you want to skip execution if another instance is still running.
Timeout-based locking
On Linux, you can specify a timeout with -t:
lockf -t 10 /var/lock/myjob.lock my_command
This waits up to 10 seconds to acquire the lock before failing.
Note: this option is not available on macOS.
Exit codes
lockf uses meaningful exit codes:
0: command executed successfully1: invalid arguments or usage error2: lock acquisition failed (for example with-n)
This makes it easy to integrate into scripts with conditional logic.
Differences between Linux and macOS
While the core behavior is similar, there are a few differences worth knowing:
-
Implementation
- Linux: typically part of
util-linux - macOS: BSD-derived implementation
- Linux: typically part of
-
Options
- Linux supports
-t(timeout) - macOS does not support timeouts
- Linux supports
-
Lock semantics
- Both use advisory locks backed by
fcntl - Locks are released automatically when the process exits or the file descriptor is closed
- Both use advisory locks backed by
For portable scripts, avoid Linux-only options like -t.
Common pattern for scripts
A widely used idiom looks like this:
#!/bin/sh
lockfile="/tmp/myjob.lock"
lockf -n "$lockfile" sh -c '
echo "Running job"
sleep 30
'
This ensures only one instance of the script runs at a time, regardless of how often it is triggered.
When not to use lockf
lockf is not suitable when:
- You need mandatory locking
- Locks must survive process crashes or reboots
- Coordination is required across NFS in unreliable setups
In those cases, higher-level coordination mechanisms or external systems are a better fit.
Summary
lockf is a simple and effective tool for process synchronization in shell scripts. When used carefully, it provides a clean solution to avoid concurrent execution on both Linux and macOS, with only minor portability considerations.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.