是否可以将一个命令的输出重定向到多个命令中?


21

据我所知,我可以使用tee命令将标准输出分为屏幕和其他文件:

command -option1 -option2 argument | tee file1 file2 file3 

是否可以使用tee将输出重定向到命令而不是文件,以便从理论上讲我可以创建命令链?


3
解释“输出信号”的含义,并描述创建“命令网络”的含义。
Janis

在linux中,每个命令都有一个输入和两个输出。它们分别标记为0(用于输入),1(用于输出)和2(用于错误输出)。当我说“输出信号”时,我想到的是1,因为我读到tee命令只会拆分标记为1的输出。当我说“命令网络”时,我不是很熟练,我不确定如何正确地定义网络从数学的角度来看,但从类型上讲,我只是想着一棵命令树,因此某些命令可以成为多个子命令的父母。
Abdul Al Hazred 2015年

感谢您的澄清。请不要使用信号一词,因为它在Unix中具有特定的含义,并且在这种情况下该词极具误导性。再次感谢。
Janis'3

在命令行中输入man -k signal以了解UNIX和Linux中此关键概念的特殊含义。杀人将是一个很好的开始。
罗布(Rob)2015年

同样,许多人将stdin stdout和stderr称为输入或输出“流”。就像条条小河一样,数据如流。您正确地试图用一个词来集体描述它们,但信号只是错误的单词。
罗布(Rob)2015年

Answers:


25

您可以在的命令行上使用命名管道(http://linux.die.net/man/1/mkfifo),tee并在命名管道上读取命令。

mkfifo /tmp/data0 /tmp/data1 /tmp/data2
cmd0 < /tmp/data0 & cmd1 < /tmp/data1 & cmd2 < /tmp/data2 &
command -option1 -option2 argument | tee /tmp/data0 /tmp/data1 /tmp/data2

command完成时,tee将关闭命名管道,这将用信号在每个的EOF(读取的0字节)/tmp/dataN,这通常终止cmdN进程。真实的例子:

$ mkfifo /tmp/data0 /tmp/data1 /tmp/data2
$ wc -l < /tmp/data0 & wc -w < /tmp/data1 & wc -c < /tmp/data2 &
$ tee /tmp/data0 /tmp/data1 /tmp/data2 < /etc/passwd >/dev/null
$ 61
1974
37

由于后台进程,外壳程序在程序输出之前返回了提示。所有三个实例均wc正常终止。


1
bash中,您可以通过进行很多安全的输入/tmp/data/{0,1,2}。再一次,在bash中,您可以使用过程替换mkfifo完全跳过
Tobias Kienzler 2015年

2
可能希望将/ dev / data0更改为/ tmp / data0。另外,感谢您以与外壳无关的方式回答问题。这比假设每个人都在使用bash更有用。
abonet

15

如果我理解正确,你正在寻找的等价tee file1 file2 file3,但不是写相同的数据三个文件file1file2而且file3,你要管相同的数据分成三个命令cmd1cmd2cmd3,即

… | ??? cmd1 cmd2 cmd3

应该等于

… | cmd1 &
… | cmd2 &
… | cmd3 &

除了那只会执行一次。

有两种方法可以做到这一点。

Ksh93,bash和zsh支持进程替换。这是管道的概括,它允许命令的参数成为一个文件,该文件在写入时会将数据作为输入传递给命令(还有输入变体,当读取该变量时,它会获取命令输出的数据) 。那是,

echo hello | tee >(cmd1)

打印hello到标准输出并且另外运行cmd1hello作为输入。

因此,例如,如果您要复制的输入somecommand并将其传递给cmd1cmd2,则可以使用

somecommand | tee >(cmd1) | cmd2

如果您的外壳不支持进程替换,则可以改用命名管道。有关如何工作的信息,请参阅Arcege的答案。命名管道不如进程替换方便,因为您必须创建它们并删除它们,然后手动启动和同步过程。它们具有完全可移植的优点,而并非所有外壳程序都支持进程替换。它们也可以用在流程替代的场景之外。

在后台,在某些系统上,进程替换在内部使用命名管道。但是,在大多数系统上,它依赖于表示文件描述符的命名文件


5
又见peemoreutils
斯特凡Chazelas

请注意,ksh88引入了进程替换。
斯特凡Chazelas


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.