How to store the output of a command in a variable at the same time as printing the output?

Use tee to direct it straight to screen instead of stdout

$ var=$(echo hi | tee /dev/tty)
hi
$ echo $var
hi

Pipe tee does the trick.

This is my approach addressed in this question.

var=$(echo "hello" | tee /dev/tty)

Then you can use $var to get back the stored variable.

For example:

var=$(echo "hello" | tee /dev/tty); echo "$var world"

Will output:

hello
hello world

You can do more with pipes, for example I want to print a phrase in the terminal, and at the same time tell how many "l"s are there in it:

count=$(echo "hello world" | tee /dev/tty | grep -o "l" | wc -l); echo "$count"

This will print:

hello world
3

A variation on Ignacio's answer:

$ exec 9>&1                                                                                                              
$ var=$(echo "hello" | tee >(cat - >&9))   
hello                                                                              
$ echo $var
hello

Details here: https://stackoverflow.com/a/12451419/1054322


Send it to stderr.

var="$(echo "hello" | tee /dev/stderr)"

Or copy stdout to a higher FD and send it there.

$ exec 10>&1
$ var="$(echo "hello" | tee /proc/self/fd/10)"
hello
$ echo "$var"
hello