刷新'tail -f'缓冲区?

刷新'tail -f'缓冲区?

我正在使用以下语句(简化版本):

tail -f -c+1 <filename>

为了将文件通过管道传输到进程。

不过,我发现末尾有许多行没有通过管道传输。

一个具体的例子是通过管道传输 mysql 文件,并在到达末尾时停止:

tail -f -c+1 mysqdump.sql | sed '/^-- Dump completed/ q0'

这不起作用 - 转储的最后一行-- Dump completed [...]没有通过管道传输到 sed。

我的猜测是tail -f,在这种情况下,缓冲区仅在已满时才会被刷新。

有谁知道我该如何解决这个问题?

=================

我找到了原因 - 描述不完整(并且代码没有表现出该行为)。

从压缩(lzma)文件进行管道传输时会发生此问题:

tail -f -c+1 <filename.lzma> | lzma -d | sed '/^-- Dump completed/ q0'

最有可能的是,tail不发送最后一个压缩块,因为它没有检测到任何新行,因为输入是二进制的。

答案1

tail -f在每个输入行后刷新。您可以使用strace(或者truss您的 UNIX 变体提供的任何用于跟踪进程的系统调用的内容)来确认这一点。

如果有不完整的行,tail -f则继续等待下一个换行符。它是专为文本文件设计的工具。如果您需要尾部二进制文件(例如,如果-- Dump completed后面没有换行符),则必须使用自定义工具。

如果您将sed的输出重定向到远离终端的位置,它将进行自己的缓冲。尝试stdbuf或者unbuffer

答案2

使用示例stdbuf -o0。参考:https://superuser.com/a/1123674/126847

tail -F cpu.log | stdbuf -o0 tr '=' ' ' | stdbuf -o0 awk '$6 > 1'

答案3

问题中调用的命令的一个问题是sed在缓冲模式下调用。

tail -f -c+1 <filename.lzma> | lzma -d | sed '/^-- Dump completed/ q0'

您需要添加-u标志:

tail -f -c+1 <filename.lzma> | lzma -d | sed -u '/^-- Dump completed/ q0'

有关详细信息,请阅读有关-u开关的信息 sed 手册页

相关内容