How to Make a Bash Script Run Only Once: Lock Files and flock Explained
This guide shows how to prevent a Bash script from being executed multiple times by detecting existing instances, using lock files with process checks, and employing the flock command for reliable atomic locking, complete with practical code examples and pitfalls to avoid.
Problem Statement
When a script is already running, you may want to prevent another instance from starting. Implementing a singleton execution for a Bash script requires reliably detecting an existing instance and exiting early.
Simple ps‑based Check
A straightforward idea is to count running copies of the script with ps -ef | grep test.sh | grep -v grep -c. If the count is greater than 1, the script exits.
#!/usr/bin/env bash
#test.sh
runCount=$(ps -ef | grep test.sh | grep -v grep -c)
if [ "${runCount}" -ge 1 ]; then
echo -e "test.sh already running,num:${runCount}"
exit 1
fi
while true; do
echo "test.sh run"
sleep 1
doneThis works, but the count is often 2 because the ps and grep commands themselves create additional processes.
File‑Lock Approach
Using a lock file mirrors the technique described in the author’s earlier article for C/C++ programs, adapted for shell scripts.
Before starting, check whether the lock file exists and whether the PID stored inside is still running.
If both are true, another instance is active and the script should exit.
Otherwise, create the lock file and write the current PID ($$) into it.
When the script terminates, remove the lock file.
#!/usr/bin/env bash
LOCKFILE=/tmp/test.lock
if [ -e ${LOCKFILE} ] && kill -0 `cat ${LOCKFILE}`; then
echo " $0 already running"
exit
fi
# Ensure the lock file is removed on exit
trap "rm -f ${LOCKFILE}; exit" INT TERM EXIT
# Write current PID to lock file
echo $$ > ${LOCKFILE}
# Your actual work here
sleep 1000
# Clean up
rm -f ${LOCKFILE}The kill -0 test verifies that the process recorded in the lock file is still alive, preventing stale lock files from blocking future runs. The trap command guarantees cleanup on interruption.
Using flock
The flock utility provides atomic file locking without the need for explicit cleanup code.
#!/usr/bin/env bash
LOCK_FILE=/tmp/test.lock
exec 99>"${LOCK_FILE}"
flock -n 99
if [ "$?" != 0 ]; then
echo " $0 already running"
exit 1
fi
# Your actual work here
sleep 1024Explanation: exec 99>"$LOCK_FILE" opens file descriptor 99 pointing to the lock file (using a high number avoids clashing with standard descriptors 0‑2). flock -n 99 attempts a non‑blocking exclusive lock; the kernel guarantees atomicity.
If the lock cannot be obtained, the script exits, otherwise it proceeds and the lock is automatically released when the process ends.
One‑Liner Alternative with Environment Variable
The man page for flock shows a compact pattern that can be placed at the very top of a script:
#!/usr/bin/env bash
[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
# Your script body
sleep 1024This line checks whether the environment variable FLOCKER is set. If not, it re‑executes the script under flock. If the lock acquisition fails, the script silently exits.
Key Takeaways
$0– script name $@ – script arguments $$ – current script PID $? – exit status of the previous command
File descriptors 0, 1, 2 correspond to stdin, stdout, stderr; higher numbers can be used for custom locks. > – redirection operator
By using either a manual lock‑file strategy or the built‑in flock command, you can ensure that only one instance of a Bash script runs at any time, avoiding race conditions and resource conflicts.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
