Pipe status after command substitution

Kinda hacky but I think you could fudge it like this.

variable=$(a | few | commands; echo ": ${PIPESTATUS[*]}")
PIPESTATUS=(${variable##*: })
variable=${variable%:*}
variable=${variable%$'\n'}

Building on ephemient's answer, if we need the output of the piped commands stored without them being mixed in with the pipestatus codes, but we don't really care what the exit codes themselves are (just that they all succeeded), we can do:

variable=$(a | few | commands; [[ ${PIPESTATUS[*]} == "0 0 0" ]])

This will check on the status of all the piped command status in the above example and if its exit code is not 0, will set $? to 1 (false)

If you want to exit with a different code instead of 1, you could capture the contents of PIPESTATUS[#], e.g. r_code=${PIPESTATUS[2]}, and then use (exit ${r_code[2]}) instead of false.

Below captures all the codes of PIPESTATUS, ensures they're all 0, and if not, sets the exit code to be the $? value of commands:

declare -a r_code 
variable=$(a | few | commands
           r_code=(${PIPESTATUS[@]})
           [[ ${r_code[*]} == "0 0 0" ]] || (exit ${r_code[2]})
)

echo ${?}         # echoes the exit code of `commands`
echo ${variable}  # echoes only the output of a | few | commands

Tags:

Bash

Pipe