Stop your shell scripts from choking on filenames with spaces
By Saket Jain Published Linux/Unix
Stop your shell scripts from choking on filenames with spaces
Technical Briefing | 11/6/2026
We have all been there. You write a script that works perfectly in testing, processing a few files in a local directory. Then you move it to production, it hits a file with a space in the name, and the whole thing explodes. It is the oldest trap in shell scripting, yet I still see people building pipelines that break as soon as they encounter a user-uploaded file named My Vacation Photo.jpg.
Why your loops are failing
The issue is word splitting. When the shell sees a command like for file in $(ls *), it takes the output of ls and splits it by whitespace. If a filename has a space, the shell treats it as two separate items. It is a fundamental design quirk of POSIX shells that bit me early in my career, and the fix is simpler than you might think.
find . -maxdepth 1 -type f -print0 | while IFS= read -r -d '' file; do process_file "$file"; done
- The -print0 flag on find forces a null character as the delimiter instead of a newline
- Setting IFS= to empty tells read not to trim leading or trailing whitespace
- The -d ” flag tells read to stop at the null character rather than the end of a line
- Always quote your variables to keep the shell from interpreting embedded spaces as arguments
If you are still using backticks or bare command substitution for file lists, stop now. It is brittle and handles weird edge cases poorly. Using find with null-terminated streams is the only way to handle arbitrary filenames reliably. Next time you are tempted to write a quick loop, remember that production data is almost always uglier than the test cases you thought of.
