Stop hardcoding your shell script exit codes
By Saket Jain Published Linux/Unix
Stop hardcoding your shell script exit codes
Technical Briefing | 7/12/2026
You probably have a script somewhere that runs a chain of commands, checks a file, and exits with 1 if something goes wrong. That works for a single task, but when your scripts start growing or get piped into other automation pipelines, relying on generic exit codes is a trap. If your script exits with 1, the caller has no idea if the error was a permission issue, a missing file, or a network timeout.
Why your exit code strategy is likely lying to you
Most developers just drop an exit 1 at the end of an if statement. But if you have multiple failure points, that code is useless. You are forcing the operator to go read logs to guess what broke, rather than surfacing the issue immediately. Use meaningful exit codes that map to your business logic or standard system error conventions.
check_db() { pg_isready -h localhost || return 2; }
check_disk() { df /var | grep -q ' 9[5-9]% ' && return 3; }
check_db || exit $?
check_disk || exit $?
- Stick to the range 1-125 for custom application errors
- Avoid 126 and 127 as they are reserved for shell-specific issues like command not found
- Reserve code 0 strictly for full success
- Document your exit codes in a comment block at the top of the file
Using specific codes allows you to handle partial failures inside your parent wrappers without parsing strings. It’s the difference between a clean automation flow that retries intelligently and a script that just stops dead, leaving you to clean up the mess manually. The next time you write a catch-all error handler, try defining an error enum instead.
