我通常使用 tee
接收管道输出数据并将其回显到标准输出,然后转发到管道数据的实际接收者。但有时会失败,我无法确切地理解原因。
我将试着用一系列示例来演示:
$ echo testing with this string | tee
testing with this string
因此,如果没有参数地将一些数据回声到
tee
上,它将在终端/标准输出上被复制/打印。请注意,这应该是tee
打印输出,因为来自echo的输出现在已经被“管道”/重定向,因此不再存在于stdout中(这里发生的与此相同)。$ echo aa | echo bb
bb
例如:echo aa
的输出被重定向到下一个命令,该命令是echo b
,它不关心输入,只输出自己的输出。
$ echo testing with this string | tee | python3 -c 'a=1'
$
现在在这里,将数据无参数地导入tee
,然后从tee
管道传输到不向终端/标准输出提供任何输出的程序-什么也不打印。我本来希望tee
在这里能够复制到标准输出,并转发到管道中的下一个命令,但显然这并没有发生。
$ echo testing with this string | tee /dev/stdout
testing with this string
testing with this string
如果我们在命令行参数/dev/stdout
下使用管道符号和tee
,我们将获得两次输出 - 正如先前得出的结论一样,必须是tee
产生了这两行打印。这意味着,当没有给它传递参数时,|tee
基本上不会打开任何文件进行复制,而只是将其输入接收到的内容转发到其输出; 但由于它是管道中的最后一个命令,所以在这种情况下,它的输出是标准输出,因此我们只得到一次输出。
这里我们得到了双重输出,因为:
tee
由于参数而将其输入流复制到/dev/stdout
(成为第一次输出);然后- 将相同的输入转发到其输出,这里的输出结果是标准输出(因为
tee
再次成为管道中的最后一个命令),从而产生第二个输出。
这也可以解释为什么之前的...| tee | python3 -c 'a=1'
没有输出任何内容:没有给tee
传递参数,因此没有打开任何文件进行复制,仅仅是将输入转发到工具链中的下一个命令 - 由于下一个命令也没有产生任何输出,因此根本没有生成任何输出。
如果上述理解是正确的,那么这个:
$ echo testing with this string | tee /dev/stdout | python3 -c 'a=1'
$
... 应该 至少打印一行(从 tee
复制到 /dev/stdout
;“转发”部分最终会被最后一个命令“吞掉”,因为它没有打印任何东西),但实际上没有。
那么,为什么会出现这种情况-我对 tee
的理解哪里出了错?
以及如何使用 tee
将输出打印到 stdout,即使其输出被转发到不会自行打印任何内容的命令?
tee
是无用的:它只是将标准输入复制到标准输出。如果您从管道中删除tee
,则会得到相同的行为。 - user1934428