Stop your subshells from swallowing your exit codes
By Saket Jain Published Linux/Unix
Stop your subshells from swallowing your exit codes
Technical Briefing | 7/25/2026
You spend half an hour writing a pipeline that pulls logs, greps for errors, and reports back. It looks great until you realize your script claims success even when the underlying command crashed. This bit me in prod back when I was greener, and it is usually because of how shell pipelines mask exit codes. We write these long, complex chains, but we forget that Bash only reports the exit status of the final command in a pipe by default.
Why your exit status is lying to you
When you run command A | command B, the shell treats this as a single unit. If command A fails to open a file or loses its network connection, the exit code from command B is all the script sees. If that final command just happens to finish cleanly, the failure in the first step vanishes into the ether. It is a silent killer for automation.
set -o pipefail
- Enable pipefail at the top of every script that involves pipes.
- Check the PIPESTATUS array if you need the specific exit code of every single command in a chain.
- Do not rely on the simple return status if your logic depends on the success of the upstream producers.
Setting this option changes the behavior of your shell for the remainder of the script execution. It forces the shell to return the exit code of the last command in the pipeline to fail, or zero if they all pass. It makes your error handling actually match what is happening on the disk and wire. Next time a log ingestion script breaks, you will at least know it failed immediately rather than finding out at 3 AM when the dashboard is empty.
