Search code examples
bashstreampipestdoutstderr

Capture both stdout and stderr in Bash


I know this syntax

var=`myscript.sh`

or

var=$(myscript.sh)

Will capture the result (stdout) of myscript.sh into var. I could redirect stderr into stdout if I wanted to capture both. How to save each of them to separate variables?

My use case here is if the return code is nonzero I want to echo stderr and suppress otherwise. There may be other ways to do this but this approach seems it will work, if it's actually possible.


Solution

  • There is no way to capture both without temp file.

    You can capture stderr to variable and pass stdout to user screen (sample from here):

    exec 3>&1                    # Save the place that stdout (1) points to.
    output=$(command 2>&1 1>&3)  # Run command.  stderr is captured.
    exec 3>&-                    # Close FD #3.
    
    # Or this alternative, which captures stderr, letting stdout through:
    { output=$(command 2>&1 1>&3-) ;} 3>&1
    

    But there is no way to capture both stdout and stderr:

    What you cannot do is capture stdout in one variable, and stderr in another, using only FD redirections. You must use a temporary file (or a named pipe) to achieve that one.