刷新“tail -f”缓冲区?

Mar*_*cus 8 pipe tail

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

tail -f -c+1 <filename>
Run Code Online (Sandbox Code Playgroud)

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

不过,我发现最后有许多行没有通过管道连接。

一个具体的例子是管道一个 mysql 文件,并在到达结束时停止:

tail -f -c+1 mysqdump.sql | sed '/^-- Dump completed/ q0'
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

从压缩 (lzma) 文件进行管道传输时会出现问题:

tail -f -c+1 <filename.lzma> | lzma -d | sed '/^-- Dump completed/ q0'
Run Code Online (Sandbox Code Playgroud)

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

Gil*_*il' 10

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

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

如果您已将sed的输出重定向到远离终端的地方,它将进行自己的缓冲。尝试stdbufunbuffer

  • 对于“sed”,如果不需要缓冲区,可以使用“-u” (2认同)