4

I'd like something that works like:

cat a > b
prog1 < b
prog2 < b

without having to create the temporary b file.

If I just had one program, I could use a pipe:

cat a | prog1

I'm wondering if a shell has syntax to support something like:

cat a (|prog1) (|prog2)

Or is there a convenient utility that can help? Something like:

cat a | fanout prog1 prog2
Michael Fox
  • 3,632
  • 1
  • 17
  • 27

1 Answers1

6

You can use tee + process substitution fork a stream of data and send it to multiple processes.

cat a | tee >(prog1) | prog2

tee takes file names as parameters. >(prog1) is replaced by a file name like /dev/fd/63 that tee can write to.

To write to more than two programs, add more process substitutions:

cat a | tee >(prog1) >(prog2) >(prog3) | prog4
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • `tee >(prog1) >(prog2) >(prog3) < a | prog4` reduces extra pipe. – codeforester May 10 '17 at 15:54
  • 1
    @codeforester: I think it's safe to assume that `cat a` is just an _example_ command, so in the general case you _do_ need a pipeline (or an _input_ process substitution). – mklement0 May 10 '17 at 22:11
  • 2
    You need to use `cat a | tee >(prog1) >(prog2) >/dev/null`, otherwise `prog1`'s output will _also_ be sent to `prog2` - try `echo hi | tee >(tr 'h' '@') | cat -n`. Then, however, you get unpredictable, asynchronous output behavior, and the background processes may not have finished yet when the next command executes. See [this answer](http://stackoverflow.com/a/43906764/45375) of mine. – mklement0 May 14 '17 at 22:14