有没有办法将一个程序的输出通过管道传输到另外两个程序中?

lon*_*gda 29 pipe

对不起,如果这是一个愚蠢的问题,但我正在尝试完成这样的事情,但在一行上:

$ prog1 | prog2
$ prog1 | prog3
Run Code Online (Sandbox Code Playgroud)

所以,我基本上想执行 prog1 并将输出分别通过管道传输到 prog2 和 prog3(不是链接管道)。起初,我试图使用 tee 但这似乎不对,因为它将输出转储到文件中(这不是我想要的)。

$ prog1 | tee prog2 | prog3 # doesn't work - creates file "prog2"
Run Code Online (Sandbox Code Playgroud)

在某些时候,我可能希望将其扩展为将输出通过管道传输到两个以上的程序,但我现在只是从简单开始。

$ prog1 | prog2
$ prog1 | prog3
$ prog1 | prog4
...
Run Code Online (Sandbox Code Playgroud)

Ign*_*ams 29

过程替换。

... | tee >(prog2) | ...
Run Code Online (Sandbox Code Playgroud)

  • @SimonRichter 这是一个 ksh93 扩展,也可以在 bash 和 zsh 中找到。 (6认同)

Arc*_*ege 17

与 Ignacio 的回答类似,您可以使用mkfifo(1).

mkfifo /tmp/teedoff.$$; cmd | tee /tmp/teedoff.$$ | prog2 & sleep 1; prog3 < /tmp/teedoff.$$; rm /tmp/teedoff.$$
Run Code Online (Sandbox Code Playgroud)

它有点冗长,但它适用于没有进程替换的系统,例如dash. 这sleep 1是处理任何竞争条件。


小智 8

有一个小型实用程序ptee可以完成这项工作:

prog1 | ptee 2 3 4 2> >(prog2) 3> >(prog3) 4> >(prog4)
Run Code Online (Sandbox Code Playgroud)

ptee不是写入文件,而是写入命令行中给出的所有文件。

聚四氟乙烯是部分pipexec


mik*_*erv 5

您不需要任何 bashisms 或特殊文件或任何这些 - 无论如何在 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
Run Code Online (Sandbox Code Playgroud)

grep为我突出显示的结果加了星号,以表明它们不仅是来自同一个流的三个结果,而且它们也是不同grep进程匹配的结果。