为什么 sed 命令会停止写入我的日志文件?

Syl*_*a1n -1 log-files sed

我在 Gnu/Linux 服务器上启动了一个应用程序myApp

./myApp &>myApp.log &
Run Code Online (Sandbox Code Playgroud)

当然,日志文件很快就会变得巨大。

我想使用sed来减少它(我知道logrotate但我的应用程序仍然是草稿)。

但是如果我使用这样的命令

sed -i "1,200d" myApp.lo
Run Code Online (Sandbox Code Playgroud)

文件确实被截断了,但在那之后,应用程序不会再将数据写入文件。

为什么?

use*_*517 5

当一个文件被打开时,系统会为其分配一个文件描述符。当文件打开时,它是通过这个 FD 访问的。

当您运行 sed 命令时,它会通过将文件复制到新文件来截断文件。您可以看到这一点,因为 inode 编号发生了变化

ls -i log
131122 log
sed -i "1,200d" log
ls -i log
131090 log
Run Code Online (Sandbox Code Playgroud)

发生的情况是文件正在写入,您通过将内容复制到另一个文件来截断它,但是原始文件由 myApp 打开并且仍在由 myApp 写入,它只是在 myApp 完成时标记为准备删除。你可以用 lsof 看到这一点。

lsof | grep myapp.log
myapp    11334  iain    1w  REG  253,2   54 131122 /home/iain/myapp.log
sed -i "1,200d" myapp.log
lsof | grep myapp.log
myapp    11334  iain    1w  REG  253,2  416 131122 /home/iain/myapp.log (deleted)
Run Code Online (Sandbox Code Playgroud)

如果可以,您应该修改您的应用程序,以便它接受一个信号,告诉它关闭然后重新打开日志文件,这将允许它与 logrotate 之类的东西一起玩。

如果您无法修改您的应用程序来处理信号,那么您可以使用 fifo。我写的如何做到这一点这里的解释前一段时间。