我在 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)
文件确实被截断了,但在那之后,应用程序不会再将数据写入文件。
为什么?
当一个文件被打开时,系统会为其分配一个文件描述符。当文件打开时,它是通过这个 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。我写的如何做到这一点这里的解释前一段时间。