将长输出导入到tee命令可能会导致截断。

5

在一些例子中,我发现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等待的方法吗?
谢谢 :-)


“第二个例子” - 如何同时读写同一个文件?我不明白第二个例子在讲什么。你的问题是什么? - KamilCuk
至于第二个例子 - 我认为我可以首先将文件连接起来,进行一些文本操作,然后再将其重定向回文件...我询问了一种延迟管道输出的方法...感谢您的出色答案! - lisrael1
1个回答

5
你遇到的问题可以简化为以下内容:
seq 50000 | tee >(wc) >(exit) >/dev/null

如果tee写入的其中一个流返回错误,则tee终止。因为管道通常带有4K缓冲区,所以对于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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接