Lesson: Hardcoded /tmp Paths Cause Race Conditions And Stale Files¶
The Problem¶
Build scripts use fixed paths in /tmp:
If two instances run simultaneously (e.g., CI parallel jobs, or a user runs a build while an update is in progress), they clobber each other's files. If an instance crashes, the stale directory is left behind forever.
Root Cause¶
Hardcoded /tmp paths (not using mktemp) create three problems:
- Race condition: Two parallel invocations write to the same directory
- Stale data: A remnant from a prior failed build can confuse a new build
- Permission mismatch: If one user creates
/tmp/ocws-buildas root, an unprivileged user can't clean it up
The same pattern appears in other scripts:
| File | Path | Issue |
|---|---|---|
build-ocws-core.sh:27 |
/tmp/ocws-build |
Race + stale dirs |
dotfiles/ocws/ocws-daemon.sh:13 |
/tmp/ocws-state, /tmp/ocws-current-song |
Race + no cleanup |
scripts/install-fonts.sh:123-126 |
/tmp/inter-font.zip |
No cleanup on failure |
scripts/install-fonts-cursors.sh:13-23 |
/tmp/JetBrainsMono.tar.xz, /tmp/Bibata.tar.xz |
No cleanup |
scripts/ocws-media-widget-updater.sh:36 |
/tmp/ocws-cover-art/*.png |
Race (fixed name) |
The Fix¶
Use mktemp for all temporary files and directories, and always add a cleanup trap:
# build-ocws-core.sh
BUILD_DIR=$(mktemp -d "/tmp/ocws-build.XXXXXX") || exit 1
trap 'rm -rf "$BUILD_DIR"' EXIT # Clean up even on failure
For the daemon state files, use a PID-based name:
Or better, use the user's runtime directory:
Verification¶
# Find hardcoded /tmp paths in scripts
grep -rn '/tmp/' scripts/ dotfiles/ --include='*.sh' | grep -v 'mktemp'
Pattern To Remember¶
Never use hardcoded names in /tmp. Two invocations will collide. Always use mktemp (for files) or $$ (for PID-unique names), and always add trap ... EXIT to clean up. /tmp is shared among all users and processes — it's not private workspace.