¿Hay alguna manera de canalizar la salida de un programa a otros dos programas?

¿Hay alguna manera de canalizar la salida de un programa a otros dos programas?

Lo siento si esta es una pregunta tonta, pero estoy tratando de lograr algo como esto pero en una línea:

$ prog1 | prog2
$ prog1 | prog3

Entonces, básicamente quiero ejecutar prog1 y canalizar la salida a prog2 y prog3 por separado (no una tubería encadenada). Al principio, estaba intentando usar tee pero no me parecía correcto porque estaba volcando la salida a un archivo (que no es lo que quiero).

$ prog1 | tee prog2 | prog3 # doesn't work - creates file "prog2"

En algún momento, probablemente querría extender esto para canalizar la salida a más de dos programas, pero por ahora estoy empezando de manera simple.

$ prog1 | prog2
$ prog1 | prog3
$ prog1 | prog4
...

Respuesta1

Sustitución de procesos.

... | tee >(prog2) | ...

Respuesta2

De manera similar a la respuesta de Ignacio, podrías usar una canalización con nombre temporal usando mkfifo(1).

mkfifo /tmp/teedoff.$$; cmd | tee /tmp/teedoff.$$ | prog2 & sleep 1; prog3 < /tmp/teedoff.$$; rm /tmp/teedoff.$$

Es un poco más detallado, pero funcionaría en sistemas que no tienen sustitución de procesos, como dash. El objetivo sleep 1es manejar cualquier condición de carrera.

Respuesta3

Hay una pequeña utilidad.pteeque hace el trabajo:

prog1 | ptee 2 3 4 2> >(prog2) 3> >(prog3) 4> >(prog4)

En lugar de escribir en archivos,pteeescribe en todos los fds que se proporcionan en la línea de comando.

pteees parte depipexec.

Respuesta4

No necesitas ningún bashismo ni archivos especiales ni nada de eso, al menos no en Linux:

% { prog1 | tee /dev/fd/3 | prog2 >&2 ; } 3>&1 | prog3 

{ { printf %s\\t%s\\t%s\\n \
    "this uneven argument list" \
    "will wrap around" to \
    "different combinations" \
    "for each line." "Ill pick out" \
    "a few words" "and grep for them from" \
    "the same stream." | 
 tee /dev/fd/3 /dev/fd/4 | 
 grep combination >&2 ; } 3>&1 |
 grep pick >&2 ; } 4>&1 | 
 grep line

different combinations  for each *line.*  Ill pick out
different combinations  for each line.  Ill *pick* out
different *combinations*  for each line.  Ill pick out

Marqué con estrella los resultados grepresaltados para mostrar que no solo eran tres resultados de la misma secuencia, sino que también eran el resultado de grepcoincidencias de procesos separados.

información relacionada