管道标准输出的tee效果输出其文件

时间:2013-04-18 21:13:21

标签: linux bash io-redirection

当我发现一个奇怪的问题时,我发现How can I send the stdout of one process to multiple processes using (preferably unnamed) pipes in Unix (or Windows)?的答案正在和grep一起玩。以下是我所期望的:

$ while [ 1 ]; do sleep 1 ; echo tick; done | tee >(grep -o ti) >(grep -o ic) >(grep tick) >/dev/null
ic
ti
tick
ic
tick
ti
^C

所有三个grep命令都应用于​​循环的输出。

但是,如果我将tee的输出传递给grep(而不是将其重定向到/ dev / null),文件上的grep就会停止工作:

$ while [ 1 ]; do sleep 1 ; echo tick; done | tee >(grep -o ti) >(grep -o ic) | grep tick
tick
tick
^C

为什么会这样?

1 个答案:

答案 0 :(得分:3)

我会猜测......

tee >(grep -o ti) >(grep -o ic) >(grep tick) >/dev/null
tee >(grep -o ti) >(grep -o ic) | grep tick

在第一个命令中,参数从左到右处理,因此grep -o ti的输出将转换为标准输出,其他两个进程替换也是如此,然后{{1}的标准输出被重定向到tee(但已经使用原始标准输出启动了进程)。

在第二个命令中,/dev/null之前已经设置了管道grep tick,因此>(grep -o ti)的标准输出沿着管道向下移动。 grep命令未选择tiic行。如果您将其更改为grep tick,您可能也会看到grep iti行。

我必须将命令调整为:

ic

查看while true; do echo tick; done | tee >(grep -o ti) >(grep -o ic) | grep i | grep -v tick ti命令。这与使用标准I / O进行缓冲有关; ic命令的输出将进入管道,因此它被完全缓冲,输出分批显示。除非我放弃了grep,否则看到替代产出将花费太长时间。

查看输出的更好的命令是:

sleep 1

输出包含如下行:

while true; do echo tick; done |
tee >(grep -o ti) >(grep -o ic) | grep i | uniq

故事的寓意可能是确保每个进程替换的输出都转到已知文件。