Is this even possible?

I'd like to run a command but capture its stdout and stderr as separate variables. Currently I'm using set -l var (cmd), which leaves stderr untouched. I can do set -l var (cmd ^&1) which will merge stdout and stderr into var, but then I can't easily separate them again.

Is there any way to get var and var_err to hold stdout and stderr from cmd?

begin; cmd ^|read -z err; end |read -z out

From fish-shell/fish-shell #2463,

An issue in your fish example is that it redirects [stdout] of both [cmd] and [read], so if the latter prints anything, it'll be carried through the pipe.

But I don't think read should ever print anything (especially to stdout) in the normal case, so this should be fine.

Edit: If the exact semantics of set var (cmd) are needed, that can be achieved using set var (printf '%s' $out) and set var_err (printf '%s' $err)


The simplest method would be to redirect one of the streams to a file:

set tmpf (mktemp)
trap "rm $tmpf" EXIT

set var (cmd ^ $tmpf)
set var_err (cat $tmpf)

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.