Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to easily find out which part of a bash/zsh pipeline failed due to `set -o pipefail`?

Tags:

bash

pipe

zsh

I have a bash/zsh command with multiple pipes | that fails when using set -o pipefail. For simplicity assume the command is

set -o pipefail; echo "123456" | head -c2 | grep 5 | cat

How do I quickly find out which command is the first to fail and why? I know I can check the exit code, but that doesn't show which part of the pipeline failed first.

Is there something simpler than the rather verbose check of building up the pipeline one by one and checking for the first failing exit code?

Edit: I removed the contrived code example I made up as it confused people about my purpose of asking. The actual command that prompted this question was:

zstdcat metadata.tsv.zst | \
tsv-summarize -H --group-by Nextclade_pango --count | \
tsv-filter -H --ge 'count:2' | \
tsv-select -H -f1 >open_lineages.txt
like image 311
Cornelius Roemer Avatar asked Sep 06 '25 03:09

Cornelius Roemer


1 Answers

In bash, use echo "${PIPESTATUS[@]}" right after the command to get the exit status for each component in a space separated list:

#!/bin/bash
$ set -o pipefail; echo "123456" | head -c2 | grep 5 | cat

$ echo ${PIPESTATUS[@]}
0 0 1 0

Beware zsh users, you need to use the lower case pipestatus instead:

#!/bin/zsh
$ set -o pipefail; echo "123456" | head -c2 | grep 5 | cat

$ echo $pipestatus
0 0 1 0

In fish you can also simply use echo $pipestatus for the same output.

like image 166
Cornelius Roemer Avatar answered Sep 07 '25 19:09

Cornelius Roemer