Linux T形三通的管道标准输出影响其文件的输出
当我发现一个奇怪的问题时,我偶然发现了这个问题的答案,并正在玩Linux T形三通的管道标准输出影响其文件的输出,linux,bash,io-redirection,Linux,Bash,Io Redirection,当我发现一个奇怪的问题时,我偶然发现了这个问题的答案,并正在玩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) >/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
为什么会发生这种情况?我冒昧猜测一下
tee >(grep -o ti) >(grep -o ic) >(grep tick) >/dev/null
tee >(grep -o ti) >(grep -o ic) | grep tick
在第一个命令中,参数是从左到右处理的,因此grep-o ti
将其输出转换为标准输出,另外两个进程替换也是如此,然后tee
的标准输出被重定向到/dev/null
(但进程已使用原始标准输出启动)
在第二个命令中,grep tick
的管道在shell在>(grep-o ti)
上工作之前已经设置好了,因此grep
的标准输出进入管道。grep tick
命令不会选择ti
和ic
行。如果您将其更改为grep i
,您可能还会看到ti
和ic
行
我必须将命令调整为:
while true; do echo tick; done |
tee >(grep -o ti) >(grep -o ic) | grep i | grep -v tick
查看ti
和ic
命令。这与使用标准I/O进行缓冲有关;来自grep
命令的输出将进入管道,因此它被完全缓冲,并且输出成批显示。除非我删除sleep 1
,否则要看到替代输出将花费太长时间
查看输出的更好命令是:
while true; do echo tick; done |
tee >(grep -o ti) >(grep -o ic) | grep i | uniq
输出包含如下行:
ictick
tick
ic
i
ti
tick
ic
tick
ti
ttick
ic
itick
tick
ic
i
ti
tiic
ictick
tick
这个故事的寓意可能是确保每个进程替换的输出都指向一个已知的文件。因此,要明确的是,循环的输出和文件重定向中两个grep的输出都将进入
grep tick
?是的,这似乎就是正在发生的事情。是的,我现在看到了。比较的输出,如果为true;做回音滴答;完成| tee>(grep-o ti)>(grep-o ic)| grep-o勾选| uniq
和为真时;做回音滴答;完成| tee>(grep-o ti)>(grep-o ic)| grep tick | uniq
。非常有趣,谢谢!