views:

1107

answers:

4

I'd like to redirect the stdout of process proc1 to two processes proc2 and proc3:

         proc2 -> stdout
       /
 proc1
       \ 
         proc3 -> stdout

I tried

 proc1 | (proc2 & proc3)

but it doesn't seem to work, i.e.

 echo 123 | (tr 1 a & tr 1 b)

writes

 b23

to stdout instead of

 a23
 b23
+27  A: 

In unix (or on a mac), use the tee command:

$ echo 123 | tee >(tr 1 a)  | tr 1 b
b23
a23

Usually you would use tee to redirect output to multiple files, but using >(...) you can redirect to another process. So, in general,

$ proc1 | tee >(proc2) ... >(procN-1) | procN

will do what you want.

Under windows, I don't think the built-in shell has an equivalent. Microsoft's Windows PowerShell has a tee command though.

dF
Thank you very much. That >(...) - concept is new to me.Note: It doesn't seem to work under Window's cmd, PowerShell and not even cygwin's bash.
secr
I'm not sure how to do it in PowerShell... It doesn't work in cygwin's bash for me either, I wonder whether it's a known limitation or a bug!
dF
This is not a POSIX construct and requires bash or ksh.You're out of luck with tcsh and dash etc.
pixelbeat
@pixelbeat: …but it can be broken down to POSIX constructs (see my answer :)
ΤΖΩΤΖΙΟΥ
I tried applying this where one of the destinations is standard output. I came up with this: "command | tee >(cat - > ./log.txt)". I wonder if there is a better way.
Harvey
+1  A: 

Look into the tee command.

dicroce
+1  A: 

Since @dF: mentioned that PowerShell has tee, I thought I'd show a way to do this in PowerShell.

PS > "123" | % { 
    $_.Replace( "1", "a"), 
    $_.Replace( "2", "b" ) 
}

a23
1b3

Note that each object coming out of the first command is processed before the next object is created. This can allow scaling to very large inputs.

Jay Bazuzi
+3  A: 
ΤΖΩΤΖΙΟΥ