【问题标题】:piping long stdout into tee command sometimes will result in truncation管道长标准输出到 tee 命令有时会导致截断
【发布时间】:2019-10-26 20:17:01
【问题描述】:

在几个示例中,我可以看到 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 等待的解决方法吗?
谢谢:-)

【问题讨论】:

  • second example - 如何同时读取和写入同一个文件?我不明白第二个例子是关于什么的。你有什么问题?
  • 对于第二个示例 - 我认为我可以将文件作为第一步,进行一些文本操作,然后才将其重定向回文件......我要求一种延迟的方法管道的输出...感谢您的出色回答!

标签: linux bash shell tee


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2017-08-11
    • 2021-04-29
    • 1970-01-01
    • 2013-04-12
    • 2018-10-09
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多