Bash try/catch — error handling patterns

Bash has no try/catch, but set -e, trap ERR, and explicit || handlers give you the same safety. Learn the patterns with copy-paste examples.

Tldr

Bash does not have try/catch. Use `set -euo pipefail` to abort on errors, `||` for per-command recovery, and `trap ERR` for a global handler. For cleanup, use `trap EXIT`.

Intro

Developers coming from Python or JavaScript look for try/catch in Bash. It does not exist, but Bash provides equivalent — and often more explicit — error-handling tools. This guide maps try/catch concepts to Bash idioms.

Steps

Name

Use strict mode as a default

Text

`set -euo pipefail` makes the script abort on the first unchecked error, the first unset variable, and the first pipeline failure. It is the closest thing to "throw on error".

Name

Handle a specific command with ||

Text

For a command that may fail, append `|| handle_error` to catch the failure inline. This is the Bash equivalent of a catch block for one operation.

Name

Add a global ERR trap

Text

A trap on ERR runs after any command fails (when set -e would abort). Use it to log context before exiting.

Name

Guarantee cleanup with EXIT trap

Text

Use trap EXIT to release resources whether the script succeeds or fails — the equivalent of a finally block.

Name

Capture and inspect exit codes

Text

When you need the exit code of a command that may fail, capture it explicitly. Do not check `$?` after another command has run.

Name

Use a wrapper function for reusable error handling

Text

For repeated operations, write a helper that runs a command and handles failure consistently.

Faq

Q

Does Bash have try/catch syntax?

A

No. Bash error handling is built on exit codes, set -e, and traps. The patterns above cover the same use cases.

Q

Why does my script keep running after an error?

A

By default Bash ignores command failures. Add set -e (or check each command) to change that behavior.

Q

How do I ignore a specific failure?

A

Append `|| true` or `|| :` to a command. The colon builtin is a no-op and suppresses the non-zero exit status.