set -euo pipefail: what each flag does in bash
- tool
- Bash
- command
- set
- flag
- -euo pipefail
- default
- all three are off
set -euo pipefail at the top of a bash script turns on three safety options: -e (errexit) stops the script at the first command that fails, -u (nounset) makes expanding an unset variable an error, and -o pipefail makes a pipeline return the status of the last command that failed instead of the status of the last command.
-e: exit on the first error
cat > errexit.sh <<'EOF'
set -e
echo "before"
false
echo "never printed"
EOF
bash errexit.shOutput · exit 1
before
-e does not trigger for commands tested by if, while, && or ||, so grep -q x file || true is the usual way to allow a failure.
-u: unset variables are errors
cat > nounset.sh <<'EOF'
set -u
echo "user: ${USER_NAME:-anonymous}"
echo "value: $UNDEFINED_VAR"
echo "never printed"
EOF
bash nounset.shOutput · exit 1
user: anonymous nounset.sh: line 3: UNDEFINED_VAR: unbound variable
Use ${VAR:-default} for variables that may legitimately be unset. The exit status for an unbound variable depends on how bash was started: bash 5.3 returns 1 when it runs a script file, as above, and 127 for bash -c '…'.
-o pipefail: failures inside pipelines count
Without pipefail, a pipeline's status is the status of its last command, so a failing grep hidden before sort goes unnoticed.
false | sort
echo "without pipefail: $?"
set -o pipefail
false | sort
echo "with pipefail: $?"Output
without pipefail: 0 with pipefail: 1
Turn the options off again
set +e, set +u and set +o pipefail disable each option, which is handy around a command whose failure you handle yourself.