Lock files for single instance in Bash Scripting - Time & Space Complexity
When using lock files in bash scripts to allow only one instance, we want to know how the script's running time changes as input or usage grows.
We ask: How does the locking process affect the script's speed when many attempts happen?
Analyze the time complexity of the following code snippet.
lockfile=/tmp/myscript.lock
if ( set -o noclobber; echo "$$" > "$lockfile" ) 2>/dev/null; then
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
# Critical section: script work here
sleep 5
rm -f "$lockfile"
trap - INT TERM EXIT
else
echo "Another instance is running. Exiting."
exit 1
fi
This script tries to create a lock file to ensure only one instance runs at a time. If the lock exists, it exits immediately.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Attempt to create a lock file once per script run.
- How many times: Exactly once per script start; no loops or retries inside this snippet.
Since the script tries to create the lock file only once, the time spent on locking does not grow with input size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 1 lock attempt |
| 100 | 1 lock attempt |
| 1000 | 1 lock attempt |
Pattern observation: The locking step happens once per run, so it stays constant regardless of input size.
Time Complexity: O(1)
This means the locking operation takes the same amount of time no matter how many times the script runs or how big the input is.
[X] Wrong: "Locking takes longer as more scripts try to run at once because it loops to wait."
[OK] Correct: This script does not retry or loop; it tries once and exits if locked, so locking time stays constant.
Understanding how locking affects script timing helps you write safe scripts that avoid conflicts without slowing down as usage grows.
What if the script retried creating the lock file multiple times with a delay? How would the time complexity change?
Practice
Solution
Step 1: Understand the role of a lock file
A lock file is used to signal that a script is already running, preventing duplicates.Step 2: Identify the main purpose
This prevents multiple script instances from running simultaneously, avoiding conflicts.Final Answer:
To prevent multiple instances of the script from running at the same time -> Option AQuick Check:
Lock file purpose = prevent duplicates [OK]
- Thinking lock files speed up scripts
- Confusing lock files with log files
- Using lock files to store data
Solution
Step 1: Check for existence before creating
The command must create the lock file only if it does not exist, so a test with [ ! -e ] is needed.Step 2: Identify the correct syntax
if [ ! -e /tmp/myscript.lock ]; then touch /tmp/myscript.lock; fi uses an if statement to check and then create the file, which is correct.Final Answer:
if [ ! -e /tmp/myscript.lock ]; then touch /tmp/myscript.lock; fi -> Option DQuick Check:
Check existence before touch = if [ ! -e /tmp/myscript.lock ]; then touch /tmp/myscript.lock; fi [OK]
- Using touch without checking file existence
- Using mkdir which creates a directory, not a file
- Overwriting lock file without check
if [ -e /tmp/myscript.lock ]; then echo "Script already running" exit 1 else touch /tmp/myscript.lock echo "Running script" rm /tmp/myscript.lock fiWhat will be the output if the lock file exists?
Solution
Step 1: Check the condition when lock file exists
If /tmp/myscript.lock exists, the if condition is true and the script echoes "Script already running" and exits.Step 2: Understand the output
Since the script exits early, it does not run or remove the lock file.Final Answer:
Script already running -> Option BQuick Check:
Lock file exists = "Script already running" [OK]
- Assuming script runs even if lock file exists
- Expecting no output when lock file exists
- Confusing lock file presence with absence
if [ -e /tmp/myscript.lock ]; then echo "Already running" exit 1 fi touch /tmp/myscript.lock # script work here rm /tmp/myscript.lockBut sometimes multiple instances run simultaneously. What is the likely problem?
Solution
Step 1: Analyze the timing of lock file creation
The script checks for the lock file, then creates it. Between these steps, another instance can start and pass the check.Step 2: Identify the race condition
This gap causes multiple instances to run simultaneously because the lock file is not created atomically with the check.Final Answer:
The lock file is created after the check, causing a race condition -> Option CQuick Check:
Race condition from delayed lock creation = The lock file is created after the check, causing a race condition [OK]
- Ignoring race conditions in lock file creation
- Forgetting to remove lock file after script ends
- Confusing file removal commands
Solution
Step 1: Understand atomic operations for locking
Using 'mkdir' to create a directory as a lock is atomic; it either succeeds or fails immediately.Step 2: Compare with other methods
Other methods like checking then touching can cause race conditions; removing lock at start is unsafe.Final Answer:
Use 'mkdir /tmp/myscript.lock' and check if it succeeds before running -> Option AQuick Check:
Atomic mkdir lock = safest method [OK]
- Using touch without atomic check
- Removing lock file before checking
- Ignoring race conditions
Ready to prove it?
Pass the test and this pattern moves unknown
