我正在创建一个LOGFILE到远程服务器。
tail -f LOGILE | gzip -c >> /faraway/log.gz
然而,当原始LOGFILE关闭并移动到存储目录时,我的tail -f似乎得到了一些奇怪的数据。
如何确保tail -f干净地停止并且压缩文件/faraway/log.gz是LOGFILE的真实副本?
编辑1
我做了一些挖掘。
/faraway/log.gz严重终止 - 在FIX消息的中途。这一定是因为我控制了上面的整个管道命令。
如果忽略最后一行,则原始LOGFILE和log.gz完全匹配!对于在大西洋上空传输的40G文件而言。
我印象非常深刻,因为它完全符合我的要求。有没有读者认为我只是"幸运"在这种情况下 - 这可能不会在将来发挥作用吗?
现在,我只需要清理一下gzip。也许如下所示向尾部PID发送kill -9可能允许GZIP正确完成其压缩。
答案 0 :(得分:0)
要获得完整副本,请使用
tail -n +1 -f your file
如果您不使用-n +1
选项,则只能获得文件的尾部。
然而,这并没有解决删除/移动文件问题。事实上,删除/移动文件问题是IPC(进程间通信)问题,或进程间协作问题。如果您没有其他流程的正确行为模型,则无法解决问题。
例如,如果其他程序将日志文件复制到其他地方,然后删除当前文件,然后程序将输出记录到该新日志文件中...显然你的尾部无法读取这些输出。
unix(和unix-like system)的相关功能值得一提:
打开文件以供进程A读取,但随后将其删除 进程B,物理内容不会立即删除, 因为它的引用计数不为零(有人仍在使用它,即 过程A)。进程A仍然可以访问该文件,直到它关闭 文件。移动文件是另一个问题:如果进程B,请移动 文件到同一物理文件系统(注意:你可能有很多 物理文件系统附加在您的系统上),进程A仍然可以 访问文件,甚至文件也在增长。这种感动是 只是为了更改名称(路径名+文件名),仅此而已。该 文件的标识(a.k.a。" i-node"在unix中)不会改变。然而 如果文件被移动到另一个物理文件系统,本地或远程, 就像文件被复制然后被删除一样。所以删除规则 提到的可以适用。
您提到的缺失行问题很有意思,可能需要对生成和移动/删除日志文件的程序/进程的行为进行更多分析。
<强> - 更新 - 强>
很高兴看到你取得了一些进展。就像我说的那样,tail
之类的进程仍然可以访问数据
在类似unix的系统中删除该文件。
你可以使用 (echo $ BASHPID&gt; / tmp / PID_tail; exec tail -n + 1 -f yourLogFile)| gzip -c - &gt; yourZipFile.gz
gzip你的日志文件,并通过
杀死tail
程序
kill -TERM `cat /tmp/PID_tail`
gzip
应该自行完成而不会出错。即使您担心gzip
会受到损害
管道信号,您可以使用这种替代方法来防止管道损坏:
( ( echo $BASHPID > /tmp/PID_tail; exec tail -n + 1 -f yourLogFile ) ; true ) | gzip -c - > yourZipFile.gz
破损的管道受true
保护,{{1}}不会打印任何内容,但会自行结束。
答案 1 :(得分:0)
来自tail
manpage:强调我的
使用--follow(-f),tail默认跟随文件 描述符,这意味着即使尾文件被重命名, tail 将继续跟踪它的结束。此默认行为是 当您真的想跟踪的实际名称时,这是不可取的 文件,而不是文件描述符(例如,日志轮换)。 使用 --follow=name 在这种情况下。这会导致尾部跟踪命名 文件以适应重命名、删除和创建的方式。
因此您提出的问题的解决方案是使用:
tail --follow=name LOGILE | gzip -c >> /faraway/log.gz
这样,当文件被删除时,tail
会停止读取它。