How to store standard error in a variable

后端 未结 18 2384
难免孤独
难免孤独 2020-11-22 12:46

Let\'s say I have a script like the following:

useless.sh

echo \"This Is Error\" 1>&2
echo \"This Is Output\" 

And I have an

18条回答
  •  说谎
    说谎 (楼主)
    2020-11-22 13:45

    Capture AND Print stderr

    ERROR=$( ./useless.sh 3>&1 1>&2 2>&3 | tee /dev/fd/2 )
    

    Breakdown

    You can use $() to capture stdout, but you want to capture stderr instead. So you swap stdout and stderr. Using fd 3 as the temporary storage in the standard swap algorithm.

    If you want to capture AND print use tee to make a duplicate. In this case the output of tee will be captured by $() rather than go to the console, but stderr(of tee) will still go to the console so we use that as the second output for tee via the special file /dev/fd/2 since tee expects a file path rather than a fd number.

    NOTE: That is an awful lot of redirections in a single line and the order matters. $() is grabbing the stdout of tee at the end of the pipeline and the pipeline itself routes stdout of ./useless.sh to the stdin of tee AFTER we swapped stdin and stdout for ./useless.sh.

    Using stdout of ./useless.sh

    The OP said he still wanted to use (not just print) stdout, like ./useless.sh | sed 's/Output/Useless/'.

    No problem just do it BEFORE swapping stdout and stderr. I recommend moving it into a function or file (also-useless.sh) and calling that in place of ./useless.sh in the line above.

    However, if you want to CAPTURE stdout AND stderr, then I think you have to fall back on temporary files because $() will only do one at a time and it makes a subshell from which you cannot return variables.

提交回复
热议问题