How to check for the return codes for processes piped to each other in ash shell?

Here is the command I am interested in:

dd if=/my/block/device | ssh myuser@otherserver "gzip > file.gz" 

Also, I know this has been answered for bash shell (i.e., using PIPESTATUS array), but I am my environment uses ash shell.


I don't know ash at all. This general workaround should work even in sh:

: > "$psf"   # to make the file empty
( dd if=/my/block/device; echo "1 $?" >> "$psf" ) \
| ( ssh myuser@otherserver "gzip > file.gz"; echo "2 $?" >> "$psf" )

Then you check the content of /tmp/pipestatus. There is a flaw: race condition, the two ( ) blocks run in parallel, they may output to the file not in the right order. I used >> so neither message will overwrite the other; the "messages" are short, so they shouldn't get interleaved; i numbered the "messages", so even if they are not in order, you can retrieve the right order later (sort, cut).

The above code is just an example anyway. More robust solution uses mktemp to create a temporary file(s), printf instead of echo. To get rid of race condition entirely, you need to write to separate files:

psd="$(mktemp -d)"
# you may want to check if the above command succeeded

( dd if=/my/block/device; printf '%s\n' "$?" > "$psd/f1" ) \
| ( ssh myuser@otherserver "gzip > file.gz"; printf '%s\n' "$?" > "$psd/f2" )

# retrieve the results here, they are in "$psd/f1" and "$psd/f2"

rm -rf "$psd"
unset psd

It's not as good as Bash's PIPESTATUS because it relies on some filesystem and ability to write there, few things can go wrong and may not be caught. Still better than nothing.

  • Note: I will upvote any answer better than mine; in particular an answer that uses ash-specific right way (if any) to solve the issue. If you write such an answer then leave me a comment under my answer. – Kamil Maciorowski Oct 29 '18 at 5:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.