Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional step in a pipeline

Given a pipeline something like "A|B|C|D|E", I want to make step C conditional on the result of step B. Something like this:

A | B | if [ $? -ne 0 ]; then C; else cat; fi | D | E

But this doesn't seem to work; C is never executed no matter what the result of B. I'm looking for a better solution.

I understand that each step of a pipeline runs in its own subshell. So I can't pass an environment variable back to the pipeline. But this pipeline is in a Gnu Parallel environment where many such pipelines are running concurrently and none of them knows any unique value (they just process the data stream and don't need to know the source, the parent script handles the necessary separation). That means that using a temporary file isn't practical, either, since there isn't any way to make the file names unique. Even $$ doesn't seem to give me a value that is the same in each of the steps.

like image 437
Dave Close Avatar asked Sep 03 '25 15:09

Dave Close


1 Answers

You can't make a pipeline conditional because the commands are run in parallel. If C weren't run until B exited, where would B's output be piped to?

You'll need to store B's output in a variable or a temporary file. For instance:

out=$(mktemp)
trap 'rm "$out"' EXIT
if A | B > "$out"; then
    C < "$out"
else
    cat "$out"
fi | D | E
like image 128
John Kugelman Avatar answered Sep 05 '25 05:09

John Kugelman