我在主机#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 更改并不总是立即显现出来。缓冲写入是根本原因(再次强调,如果我没记错的话)。
如果你必须得到每一句台词那么你就必须下马。