A command that writes some output and then fails can look successful when piped into a consumer that exits normally. For batch processing, checking only the consumer may allow partial data to continue through the workflow. Bash offers both an aggregate pipeline policy and individual stage statuses.
The GNU Bash pipeline reference explains that pipefail uses the rightmost nonzero stage status, or zero when all stages succeed. The Bash reference manual also documents the PIPESTATUS array. The practical detail is to copy that array immediately after the pipeline.
Prerequisites
Use Bash on Linux with cat available. Save this complete program as pipeline.sh. It is a Bash script, so invoke it with bash rather than sh. It sends fixture output to /dev/null and creates no files.
#!/usr/bin/env bash
set -u
produce() { printf 'partial\n'; return 7; }
produce | cat > /dev/null
ordinary=$?
set -o pipefail
produce | cat > /dev/null
status=("${PIPESTATUS[@]}")
[[ $ordinary -eq 0 ]] || exit 1
[[ ${status[0]} -eq 7 && ${status[1]} -eq 0 ]] || exit 1
produce | cat > /dev/null
aggregate=$?
[[ $aggregate -eq 7 ]] || exit 1
printf 'default status: %s\n' "$ordinary"
printf 'stage statuses: %s %s\n' "${status[0]}" "${status[1]}"
printf 'pipefail status: %s\n' "$aggregate"
Run and expected output
bash pipeline.sh
default status: 0
stage statuses: 7 0
pipefail status: 7
Understand what was captured
The producer always emits a short partial record and returns 7. The consumer reads it successfully and returns 0. Before pipefail is enabled, the pipeline reports the consumer's successful status. After enabling pipefail, the aggregate reports the producer failure.
The array assignment copies the status of both stages from left to right. Its expansion happens before the assignment itself updates shell command status. An intervening echo, test, or assignment could replace PIPESTATUS, so capture first and explain later.
The demonstration repeats the pipeline to inspect the aggregate status separately. This keeps the two capture techniques clear. In application code, decide whether you need an overall success decision or detailed stage diagnostics, then preserve the relevant values before executing another command.
Apply it to batch work
For an export-and-transform pipeline, treat a nonzero producer status as a failed export even if the transformer accepted all bytes it received. Include the stage statuses in diagnostics, but avoid publishing the partial output as a successful result. Process status and output completeness are related checks, not interchangeable evidence.
This program deliberately does not enable set -e because failures are the data being examined. If you use errexit in a larger script, handle an expected pipeline failure in an explicit conditional before collecting and evaluating statuses. Otherwise, the shell may exit before the diagnostic code runs.
Edge cases and troubleshooting
With several failing stages, pipefail reports the rightmost failure rather than a list. Preserve PIPESTATUS to identify every failing stage. Some pipelines intentionally stop reading early; the producer may then receive a broken-pipe signal. Define whether that is expected for that specific workflow instead of treating all nonzero statuses identically.
If the script reports an array syntax error, check that it is running under Bash. If stage statuses unexpectedly contain only one value, look for a command inserted between the pipeline and the capture. The fixture tests a controlled producer failure; it does not simulate disk-full conditions or signal handling.
Continue with the Linux tutorials.