将长标准输出管道传输到 tee 命令有时会导致截断

piping long stdout into tee command sometimes will result in truncation

在几个示例中,我可以看到 tee 不会等待 stdout 完成,这会导致一些错误行为。

第一个例子:
seq 50000|tee >(wc) >(head -2) >/dev/null
将输出:

                1
                2
  12773   12774   65536

而不是

                1
                2
  50000   50000  288894

第二个例子:
cat f.txt|grep abc|tee f.txt >/dev/null
在此示例中,文件更新将起作用,仅当文件是短文件时,但如果文件是长文件,有时 tee 将在 cat 完成之前开始写入,并且文件更新将仅在第一个 'cat' 过渡。

你可以说 tee 只是用于重定向到文件,但我也看到了 tee 的那些用法。
我知道 pee 命令没有这个错误,但有人知道让 tee 等待的解决方法吗?
谢谢:-)

您遇到的问题可以简化为:

seq 50000 | tee >(wc) >(exit) >/dev/null

如果其中一个流 tee 向 returns 写入错误,tee 将终止。因为管道一般都是用4K的buffer来缓冲的,所以wc抓一些线来处理就够了

head -n2 打印两行后关闭流。

您可以通过告诉 tee 在错误时打印一些内容来查看错误:

# seq 50000 | tee --output-error=exit >(wc) >(exit) >/dev/null
tee: /dev/fd/62: broken pipe

您可以使用 -p--output-error=warn 来解决问题,告诉 tee 在写入管道时出错后继续:

seq 50000 | tee -p >(wc) >(head -n2) >/dev/null

或者使用处理完输入后不退出的命令,比如sed:

seq 50000 | tee >(wc) >(sed -n '1,2p') >/dev/null