In my bash scripts, I often use pipes and would like to know which stage of the pipe was causing the problem in case of errors. The basic structure of such snippets is:
#!/bin/bash
ProduceCommand 2>/dev/null | ConsumeCommand >/dev/null 2>&1
PipeErrors=("${PIPESTATUS[@]}")
[[ "${PipeErrors[0]}" -eq '0' ]] || { HandleErrorInProduceCommand; }
[[ "${PipeErrors[1]}" -eq '0' ]] || { HandleErrorInConsumeCommand; }
Now (interestingly enough for the first time) I am in a situation where it would be great if I could use either tee
or pee
. But what happens to $PIPESTATUS
when using these commands? For example:
#!/bin/bash
ProduceCommand 2>/dev/null | tee >(ConsumeCommand1) >(ConsumeCommand2) >/dev/null 2>&1
PipeErrors=("${PIPESTATUS[@]}")
or
#!/bin/bash
ProduceCommand 2>/dev/null | pee ConsumeCommand1 ConsumeCommand2 2>/dev/null
PipeErrors=("${PIPESTATUS[@]}")
I believe that in both cases ${PipeErrors[0]}
reflects the error status of ProduceCommand
. Further, it would be logical to assume that ${PipeErrors[1]}
reflects the error status of tee
or pee
itself, respectively.
But this leads me into at least two understanding problems:
What is the error status (return value) of
tee
orpee
? I didn't find precise statements about that in the man pages. Do they return a hard-coded error status if one of the consume commands fails, or do they relay the error status of the consume commands somehow (asssh
does, for example)? If the former is the case, how can we find out which of the consume commands is the culprit? If the latter is the case, which error status is relayed? Is it simply that of the command which fails first?AFAIK, bash or the
tee
orpee
command itself, respectively, internally use pipes (fifos) to getProduceCommand
's output to the consume commands. This means that we have a pipe whose (first and in this case, only) receiving side is a pipe itself. This should not influence$PipeErrors
in the sample code above, but I am really unsure.
Could somebody shed some light on this?