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

标签 linux bash shell tee

在几个示例中,我可以看到 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 写入的流之一返回错误,则 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

关于linux - 将长标准输出管道传输到 tee 命令有时会导致截断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58574382/

相关文章:

linux - 连接 Jenkins 从站到主站已中止 : Ping response time is too long or timed out

linux - 清除文件而不更改其时间戳

linux - 在 shell 后台运行进程 2 分钟,然后在 2 分钟之前终止它 BASH

bash - 使用固定种子改组文件行?

shell - 无法在 Ubuntu 18.04 上将 AEM 作为服务启动

javascript - curl 命令查看从测试程序发送到 Linux 上的网络服务器的消息

bash - IFS= 在此 bash 循环 : `cat file | while IFS= read -r line; do ... done` 中做什么

linux - 在服务器上添加启动脚本

bash - Shell 脚本 - 测试目录是否存在于当前目录或父/祖先目录中

正则表达式删除 block 注释也删除 * 选择器