C'è un modo per convogliare l'output di un programma in altri due programmi?


28

Scusate se questa è una domanda sciocca ma sto cercando di realizzare qualcosa del genere ma su una riga:

$ prog1 | prog2
$ prog1 | prog3

Quindi, sostanzialmente voglio eseguire prog1 e reindirizzare l'output su prog2 e prog3 separatamente (non una pipe concatenata). All'inizio, stavo cercando di usare tee ma non mi sembrava giusto perché stava scaricando l'output su un file (che non è quello che voglio).

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

Ad un certo punto, probabilmente vorrei estenderlo al piping dell'output a più di due programmi, ma per ora sto iniziando semplicemente.

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

Penso che zsh possa farlo.
Keith

Risposte:



16

Simile alla risposta di Ignacio, è possibile utilizzare una pipe denominata temporanea utilizzando mkfifo(1).

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

È un po 'più dettagliato, ma funzionerebbe su sistemi che non hanno una sostituzione di processo, come dash. L' sleep 1obiettivo è gestire qualsiasi condizione di gara.


6

C'è un piccolo ptee di utilità che fa il lavoro:

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

Invece di scrivere su file, ptee scrive su tutti i file fds che sono indicati sulla riga di comando.

ptee fa parte di pipexec .


4

Non hai bisogno di alcun bashismo o file speciale o altro - non in Linux comunque:

% { 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

Ho segnato i risultati grepevidenziati per me per dimostrare che non erano solo tre risultati dello stesso flusso, ma erano anche il risultato di grepcorrispondenze di processo separate .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.