Bash – copy consumed output to stdout when stdout is redirected to a file

bashio

Given a command the output of which is being processed by, for example, grep I also want the actual output to be included in the log file for debugging purposes.

For example if I have the following

useful=$(curl -s http://example.com/some/data | grep 'useful line')
echo "useful=$useful"

I want to see

This page has a number of lines in it, but'
useful lines are the only ones I care about
except when something goes wrong and then
I'd really like to see what the heck was in
the output that grep consumed.
useful=useful lines are the only ones I care about

This can be done with tee like so

useful=$(curl -s http://example.com/some/data | tee /proc/$$/fd/1 | grep 'useful line')
echo "useful=$useful"

but if stdout is being redirected to a file tee clobbers the rest of your log file. tee -a fails in largely the same way.

Best Answer

tee the stdout stream to the controlling terminal device /dev/tty.

(
exec 1> >(tee -a stdout.log)
: > stdout.log
#var="$(echo -e "one\ntwo" | tee /dev/tty | grep one)"
var="$(echo -e "one\ntwo" | tee -a /dev/tty stdout.log | grep one)"
echo "var=$var"
)

cat stdout.log
# one
# two
# var=one
Related Question