为什么在 samba 安装上对文件进行 tail -F 时会丢失一些行?

为什么在 samba 安装上对文件进行 tail -F 时会丢失一些行?

我在主机#1上有一个进程,它会定期将内容附加到文件 - foo.log。

我在主机 #2 上有一个进程,它可以通过 samba 挂载访问 foo.log。然后我在该文件上调用 tail -F 来实时观察其输出。

一些行被 tail -F “丢失”或者丢弃。

使用 strace 进行的调查表明,一些 reads() 返回了一组空字节。

nanosleep({1, 0}, NULL)                 = 0                                               
fstat(3, {st_mode=S_IFREG|0660, st_size=54526947, ...}) = 0                               
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8192) = 630
read(3, "", 8192)                       = 0    

当然,有些行是正确返回的,所以这些块并不总是空的。

此外,在托管 foo.log 的主机 #1 的文件系统上直接调用相同的 strace 命令永远不会显示来自 strace 的空字节读取块。

就好像主机 #1 上的 samba 服务器可以看到文件大小的变化,但无法实时查看内容。如果 samba 等一秒钟再试一次,我敢打赌内容会在那里。

有没有办法让 samba 允许实时对文件进行 tail -F 而不丢失行?

答案1

简而言之,没有办法强制 tail 向您显示发布到已挂载文件系统的每一行。

我不知道 tail 的内部工作原理(我最近没有看过源代码)但如果我没记错的话,它会不断地寻找文件的末尾,当 EOF 移动时,它会报告从上次寻找到 EOF 的内容。

这听起来应该可以按预期工作,但由于文件系统的挂载特性,EOF 更改并不总是立即显现出来。缓冲写入是根本原因(再次强调,如果我没记错的话)。

如果你必须得到每一句台词那么你就必须下马。

相关内容