In this lesson, you will learn how to prevent multiple instances of the same script from running simultaneously by using a simple lock-file primitive.
The Problem: Race Conditions
When you run a script that performs critical tasks—like writing to a shared database or processing a specific log file—you don’t want two copies of that script running at once. If they both try to modify the same resource at the same time, you create a "race condition," which often leads to corrupted data or system instability.
Using a Lock-file as a Guard
A lock-file acts as a "Do Not Disturb" sign on your script’s door. Before the script begins its work, it checks if a specific file exists. If it does, the script assumes another instance is already running and exits immediately. If the file does not exist, the script creates it, does its work, and deletes the file when finished.
To implement this, we use the mkdir command. Unlike standard file creation, mkdir is an atomic operation—the operating system guarantees that only one process can successfully create a specific directory at any given moment.
Implementation Pattern
LOCKFILE="/tmp/my_script.lock"
# Attempt to create the lock directory
if mkdir "$LOCKFILE" 2>/dev/null; then
# If successful, register a trap to remove the lock on exit
trap 'rmdir "$LOCKFILE"; exit' EXIT INT TERM
echo "Lock acquired. Running critical task..."
sleep 10 # Simulating work
else
echo "Error: Another instance is already running."
exit 1
fi
In this code:
- We try to create a directory named
my_script.lock. - If
mkdirsucceeds (returns exit code 0), we have "locked" the resource. We then set atrapto ensure that when the script finishes (or is interrupted), the directory is removed so the next instance can run. - If
mkdirfails, it means another process already holds the lock, so we exit gracefully.
This simple mechanism ensures that your script remains a "singleton," providing a clean, predictable environment for your system resources.
Key Takeaway: By using an atomic directory creation as a lock-file, you can ensure that only one instance of your script executes at a time, preventing data corruption and resource conflicts.