22

I need to see output on the screen and at the same time grep the output and send grep result to variable. I think it can be done with tee but I can't figure out how exactly. I tried

mycommand | tee myvar=$(grep -c keyword)
mycommand | tee  >(myvar=$(grep -c keyword))

but this does not work. How should it be, preferrably without writting to files?

Putnik
  • 2,507
  • 6
  • 29
  • 43

3 Answers3

28

You would do this:

myvar=$( mycommand | tee /dev/tty | grep -c keyword )

Use tee to pipe the output directly to your terminal, while using stdout to parse the output and save that in a variable.

16

You can do this with some file descriptor juggling:

{ myvar=$(mycommand | tee /dev/fd/3 | grep keyword); } 3>&1

Explanation: file descriptor #0 is used for standard input, #1 for standard output, and #2 for standard error; #3 is usually unused. In this command, the 3>&1 copies FD #1 (standard output) onto #3, meaning that within the { }, there are two ways to send output to the terminal (or wherever standard output is going).

The $( ) captures only FD #1, so anything sent to #3 from inside it will bypass it. Which is exactly what tee /dev/fd/3 does with its input (as well as copying it to its standard output, which is the grep command's standard input).

Essentially, FD #3 is being used to smuggle output past the $( ) capture.

-2

You can use like below. If you want to append use -a option with tee remember it will create a file with your variable name.

$ ls | tee $(echo asktyagi)
asktyagi1

$ ls -lthr
total 12K
-rw-rw-r--. 1 asktyagi asktyagi    8 Oct 29 08:54 asktyagi1
-rw-rw-r--. 1 asktyagi asktyagi   23 Oct 29 08:54 asktyagi
asktyagi
  • 3,038