Apakah ada cara untuk menyalurkan output dari satu program ke dua program lainnya?

28

Maaf jika ini pertanyaan konyol tapi saya mencoba menyelesaikan sesuatu seperti ini tetapi dalam satu baris:

$ prog1 | prog2
$ prog1 | prog3

Jadi, pada dasarnya saya ingin menjalankan prog1 dan pipa output ke prog2 dan prog3 secara terpisah (bukan pipa berantai). Pada awalnya, saya mencoba menggunakan tee tapi itu sepertinya tidak benar karena itu membuang output ke file (yang bukan yang saya inginkan).

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

Pada titik tertentu, saya mungkin ingin memperpanjang ini untuk menyalurkan output ke lebih dari dua program tapi saya baru mulai sederhana untuk saat ini.

$ prog1 | prog2
$ prog1 | prog3
$ prog1 | prog4
...
longda
sumber
Saya pikir zsh dapat melakukan ini.
Keith

Jawaban:

28

Substitusi proses.

... | tee >(prog2) | ...
Ignacio Vazquez-Abrams
sumber
1
IIRC yang merupakan ekstensi bash dan tidak ditemukan di sh POSIX standar.
Simon Richter
6
@SimonRichter Ini adalah ekstensi ksh93, juga ditemukan di bash dan zsh.
Gilles 'SANGAT berhenti menjadi jahat'
16

Mirip dengan jawaban Ignacio, Anda bisa menggunakan pipa bernama sementara menggunakan mkfifo(1).

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

Ini sedikit lebih bertele-tele, tetapi itu akan bekerja pada sistem yang tidak memiliki substitusi proses dash. The sleep 1adalah untuk menangani kondisi ras.

Arcege
sumber
6

Ada PTT utilitas kecil yang melakukan pekerjaan:

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

Alih-alih menulis ke file, PTee menulis ke semua fds yang diberikan pada baris perintah.

PTee adalah bagian dari pipexec .

Andreas Florath
sumber
4

Anda tidak memerlukan bashisme atau file khusus apa pun - tidak di 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

Saya membintangi hasil yang grepdisorot untuk saya menunjukkan bahwa mereka bukan hanya tiga hasil dari aliran yang sama, tetapi mereka juga hasil dari grepkecocokan proses yang terpisah .

mikeserv
sumber