Question

I know that using a pipe I can redirect the output of a command to another command:

cmd1 | cmd2

Also when I use something like:

cmd1 | cmd2 | cmd3

the second pipe make that cmd3 to take the output of cmd2. My question is: is it possible to make cmd3 to take the output of cmd1?

Was it helpful?

Solution

You can use tee:

cmd1 | tee >(cmd2) >(cmd3)

or pee:

cmd1 | pee "cmd2" "cmd3"

tee should be installed by default in all Unix like systems, while pee can be found in moreutils package.

OTHER TIPS

You can do it with tee and named pipes:

 $ fifo=/tmp/1to3
 $ mkfifo $fifo
 $ cmd1 | tee $fifo | cmd2 & cmd3 <$fifo

IF guaranteed order of execution of cmd2 and cmd3 and/or guaranteed order of their output (if any) are a concern, using process substitution (>(...)) or named pipes (FIFOs) is NOT an option.
Instead:

  • Use the pee utility as demonstrated in Radu Radeanu's answer, if installing it is an option (and it's available for your platform).

  • Otherwise, use a temporary file as follows:

cmd1 | { f=$(mktemp) && cat >$f; cmd2 <$f; cmd3 <$f; rm $f; }

(On OSX, use mktemp -t tmp instead of just mktemp; mktemp -t XXXX would work on both platforms).


Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top