Bash & Shell Scripting DISCUSSION

Is set -euo pipefail enough to make a Bash script stop on errors, and when does set -e not exit?

Started by baha Bash set -epipefailnounseterror handlingtrap ERR
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

Is set -euo pipefail enough to make a Bash script stop on errors, and when does set -e not exit?

#1

A nightly backup script of mine continued after cd /mnt/backup failed because the disk was not mounted, and the archive was written into the wrong directory. I have since added set -euo pipefail at the top as many guides recommend.

What does each of the three options do, and are there cases where the script still carries on after a failed command? I would like to know how far I can rely on it.

Community replies 4

Re: Is set -euo pipefail enough to make a Bash script stop on errors, and when does set -e not exit?

#2

set -e makes the shell exit when a command returns a non-zero status. set -u turns the expansion of an unset variable into an error, which catches a misspelled variable name before an empty value ends up in a path. set -o pipefail changes the status of a pipeline: normally it is the status of the last command only, so mysqldump db | gzip > db.sql.gz reports success even when the dump failed, because gzip was happy. With pipefail the pipeline fails if any stage failed.

Re: Is set -euo pipefail enough to make a Bash script stop on errors, and when does set -e not exit?

#3

set -e has deliberate exceptions. A failing command does not end the script when it is the condition of if, while or until, when it is on the left of && or ||, or when it is negated with !. That is what allows if grep -q pattern file; then to work.

The surprising consequence: if a function is called in one of those positions, as in if do_backup; then or do_backup || echo failed, errexit is switched off for everything inside the function, and commands in it that fail are ignored.

Re: Is set -euo pipefail enough to make a Bash script stop on errors, and when does set -e not exit?

#4

Command substitutions hide failures as well. In local stamp=$(some_command) the status that counts is that of local, which succeeds, so the script continues with an empty variable when the command fails. The same applies to export var=$(...) and readonly. Declare and assign in two steps: local stamp; stamp=$(some_command).

The opposite problem also exists: commands that use a non-zero status for a normal result. grep returns 1 when nothing matches, and that ends the script under set -e. Write grep pattern file || true or put it in an if.

Re: Is set -euo pipefail enough to make a Bash script stop on errors, and when does set -e not exit?

#5

Treat the options as a safety net and still check the steps that matter explicitly: cd /mnt/backup || { echo "backup disk not mounted" >&2; exit 1; }. An explicit check documents the intent and gives a useful message.

Add traps for the rest: trap 'rm -f "$tmpfile"' EXIT cleans up however the script ends, and trap 'echo "error at line $LINENO" >&2' ERR tells you where it stopped. With set -u, optional arguments need a default, ${1:-}. Exit codes above 128 mean a signal: 130 is Ctrl-C (128 + 2), and 141 is SIGPIPE (128 + 13), which pipefail can expose in pipelines such as cmd | head -n 1.

TEP COMMUNITY