452 words, 3 min read

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:

  1. Opens (and creates if needed) the lock file
  2. Acquires an exclusive lock
  3. Executes my_command
  4. 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 successfully
  • 1: invalid arguments or usage error
  • 2: 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
  • Options

    • Linux supports -t (timeout)
    • macOS does not support timeouts
  • Lock semantics

    • Both use advisory locks backed by fcntl
    • Locks are released automatically when the process exits or the file descriptor is closed

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.