Zsh: save stdout, stderr, and return value of command to different variables (without temp file)
This is something worth sharing. The idea was based on this SO answer, and I cooked up this particular implementation to remove potential race conditions, with input from Mathias Fredriksson1. See mafredri/zsh-async#1, and in particular this comment for explanation.
# The following construct evaluates "$@" and saves output on stdout in the
# parameter stdout, output on stderr in the parameter stderr, and return value
# in the parameter return.
#
# The idea was based on http://stackoverflow.com/a/18086548/1944784, but this
# implementation is completely race-condition-free. The implementation was
# refined during my exchange with Mathias Fredriksson @mafredri, in
# https://github.com/mafredri/zsh-async/issues/1. See mainly
# https://github.com/mafredri/zsh-async/issues/1#issuecomment-121468958, where
# the advantage of this implementation is explained.
unset stdout stderr ret
eval "
$(
{
stdout=$(eval "$@")
ret=$?
typeset -p stdout ret
} 2> >(stderr=$(cat); typeset -p stderr)
)"
Also available as a gist.
Mathias (@mafredri) is the author of the lovely zsh-async library, and a maintainer of sindresorhus/pure. He forever revolutionalized my prompt.↩︎