Capture stdout to a variable but still display it in the console Capture stdout to a variable but still display it in the console bash bash

Capture stdout to a variable but still display it in the console


Duplicate &1 in your shell (in my examle to 5) and use &5 in the subshell (so that you will write to stdout (&1) of the parent shell):

exec 5>&1FF=$(echo aaa|tee >(cat - >&5))echo $FF

Will print aaa two times, ones because of the echo in the subshell, and second time print the value of the variable.

In your code:

exec 5>&1VAR1=$(for i in {1..5}; do sleep 1; echo $i; done | tee >(cat - >&5))# use the value of VAR1


Op De Cirkel's answer has the right idea. It can be simplified even more (avoiding use of cat):

exec 5>&1FF=$(echo aaa|tee /dev/fd/5)echo $FF


Here's an example capturing both stderr and the command's exit code. This is building on the answer by Russell Davis.

exec 5>&1FF=$(ls /taco/ 2>&1 |tee /dev/fd/5; exit ${PIPESTATUS[0]})exit_code=$?echo "$FF"echo "Exit Code: $exit_code"

If the folder /taco/ exists, this will capture its contents. If the folder doesn't exist, it will capture an error message and the exit code will be 2.

If you omit 2>&1then only stdout will be captured.