🎓 A1Learner
🔍
0 of 46 lessons completed

Bash Pipelines and Pipefail

A pipeline joins commands so the output of one becomes the input of the next. Its exit status normally comes from the last command only.

Read every command's status with PIPESTATUS

false fails and true succeeds. PIPESTATUS holds both results, in pipeline order.

false | true
echo "${PIPESTATUS[0]} ${PIPESTATUS[1]}"

Without pipefail, only the last command counts

The first command fails, but the last command succeeds. The pipeline status is therefore zero, and the failure stays hidden.

false | true
echo "pipeline status: $?"

Pipefail exposes a failing middle command

With pipefail on, the middle command fails and the whole pipeline fails. PIPESTATUS still shows the middle command's real status.

set -o pipefail
true | false | true
echo "middle: ${PIPESTATUS[1]} status: $?"

Example

set -o pipefail
printf 'red\nblue\n' | grep "green" | wc -l
echo "pipeline status: $?"

Key points

  • Pipeline: a chain of commands joined by |, passing output along.
  • PIPESTATUS: an array holding the exit status of each command in the last pipeline.
  • set -o pipefail: makes a pipeline fail if any command in it fails.
  • Without pipefail, a failing middle command can hide behind a passing last command.
  • Read PIPESTATUS at once: the next command replaces it.

In this example, pipefail is turned on first. The pipeline prints two colours, then grep looks for green and finds none, so grep fails. The wc command still prints a count of zero, but pipefail makes the whole pipeline fail. The last line prints that failing status.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

With set -o pipefail, what is the exit status of false | true?