开发者

Pipe status after command substitution

开发者 https://www.devze.com 2023-01-29 17:23 出处:网络
I\'d like to send the result of a series of commands to a variable: variable=$(a | few | commands) However, the command substitution resets PIPESTATUS, so I can\'t inspect where it went wrong after

I'd like to send the result of a series of commands to a variable:

variable=$(a | few | commands)

However, the command substitution resets PIPESTATUS, so I can't inspect where it went wrong after the fact. One solution would be to use mktemp and put the开发者_运维知识库 result there temporarily:

variable_file=$(mktemp) || exit 1
a | few | commands > $variable_file
exit_codes="${PIPESTATUS[*]}"
variable=$(<$variable_file)

Is there a more elegant solution?


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
0

精彩评论

暂无评论...
验证码 换一张
取 消