Shell scripts that survive spaces and silent failures
Updated

Quote every expansion, fail fast with strict mode, and test the unhappy path: shell habits that prevent 3 AM pages.
Shell scripts fail in two famous ways: they choke on a filename with a space, or they fail silently halfway and report success. Both come from defaults that made sense in 1979. Three habits fix most of it.
Quote, strict mode, trap
Quote every expansion. A variable holding a path with a space becomes two arguments when unquoted. Quoting is the default; an unquoted expansion needs a written reason.
Fail fast in automation. Strict mode stops the script on errors, unset variables and pipeline failures instead of marching on with garbage. Test the unhappy path on purpose: a missing file should stop the script loudly.
Trap your cleanup. Temp files get unique names and a removal rule on exit. Scripts that share fixed temp names corrupt each other when two copies run at once.
Worked example: a fictional deploy script
The context below is fictional. Fictional script deploy.sh (fictional) copies a release into a directory whose path contains a space, then restarts a service. Unquoted, the copy splits the path and half the release lands in the wrong place; without strict mode the restart still reports success.
The rewrite quotes every path, enables strict mode, and creates its staging dir with mktemp plus an exit trap. The test is a path with spaces and a missing source file: the first must succeed, the second must fail loudly with a nonzero exit. Both behave after the rewrite.
Checklist: a script you can schedule
- Every expansion quoted, or justified in a comment.
- Strict mode on for automation scripts.
- Temp files unique with exit cleanup.
- Unhappy path tested: missing input fails loudly.
Related reading
- Hands on: Fix the Shell Script with Spaced Names.
- DevOps Foundations Module 1 covers the shell sequence.
Straight answers
Frequently asked questions
Is set -euo pipefail always right?
For automation, yes as the default. For interactive helpers, no. Know which kind of script you are writing.
Why did my loop break on one filename?
An unquoted expansion split on spaces. Quote every variable expansion unless you can state why this one is safe.
How do I clean up temp files safely?
Create them with mktemp and remove them on exit with a trap. Fixed names in /tmp collide and leak.