set -o pipefail: Usage & Common CI Gotchas
pipefail makes a pipeline return failure if ANY command in it fails, not only the last one.
Without pipefail a pipeline reports only the exit status of its final command, so a failing build piped into tee looks green. pipefail closes that hole - and introduces its own SIGPIPE edge cases.
What it does
By default a pipeline's exit status is that of its last command. set -o pipefail changes it to the rightmost command that exited non-zero (or zero if all succeeded), so failures anywhere in the pipe are not masked.
Common usage
set -o pipefail
npm run build 2>&1 | tee build.log # build failure now propagates
set -euo pipefail # the standard CI preamble
# inspect per-stage status in bash:
cmd1 | cmd2; echo "${PIPESTATUS[@]}"Options
| Item | What it does |
|---|---|
| set -o pipefail | Enable: pipeline fails if any stage fails |
| set +o pipefail | Disable |
| ${PIPESTATUS[@]} | Bash array of each stage's exit code |
| set -euo pipefail | Common combined hardening preamble |
Common errors in CI
pipefail is a bash/zsh feature - POSIX sh (dash) does not have it, so set -o pipefail errors with "set: Illegal option -o pipefail" when the step runs under /bin/sh; set the shell to bash. It can also surface "false failures": a producer that gets SIGPIPE because head closed the pipe early exits 141, and pipefail then fails the step (see head/tail). Decide per-pipeline whether early termination is success.