Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tee into fd's instead of named pipes

Tags:

bash

pipe

I want to take stdout of a process and analyze it with three different programs. I have been able to use named pipes, but can I use fd's instead.

Here's what works so far:


exec 3< <(myprog)
tee p1 p2 >/dev/null <&3

cat p1|ap1 &
cat p2|ap2 &

p1 and p2 were created with mkfifo. ap1 and ap2 are analysis programs. I don't know if I'm saying this right, but is there a way to tee into two new fd's instead? Something like this:


exec 3< <(myprog)
tee >&4 >&5 <&3

cat <&4|ap1 &
cat <&5|ap2 &

like image 600
User1 Avatar asked Aug 26 '10 18:08

User1


1 Answers

You almost had it:

myprog | tee >(ap1) >(ap2) >(ap3) >/dev/null

Note that ap1 can be a function. If you want the function to have access to your script's argument, call it with "$@", i.e.,

ap1 () {
  # here the script arguments are available as $1, $2, ...
}
# ditto for ap2, ap3
myprog | tee >(ap1 "$@") >(ap2 "$@") >(ap3 "$@") >/dev/null

If your shell doesn't support >() (bash, ksh and zsh do, but it's not POSIX), but your OS nonetheless supports /dev/fd (most unices do, including Solaris, Linux, *BSD, OSX and Cygwin), you can use explicit fd shuffling.

{ { { myprog | tee /dev/fd/3 /dev/fd/4 |
      ap1 >&2
    } 3>&1 |
    ap2 >&2
  } 4>&1 |
  ap3 >&2
}
like image 127
Gilles 'SO- stop being evil' Avatar answered Oct 10 '22 23:10

Gilles 'SO- stop being evil'