从Unix Power Tools,第3版:清空文件部分,而不是删除文件:
如果活动进程打开了文件(对于日志文件来说并不罕见),则删除该文件并创建一个新文件不会影响日志记录程序。这些消息只会继续转到不再链接的文件。清空文件不会破坏关联,因此清除文件不会影响日志记录程序。
(重点是我的)
我不明白为什么程序会继续记录到已删除的文件。是因为文件描述符条目没有从过程表中删除吗?
从Unix Power Tools,第3版:清空文件部分,而不是删除文件:
如果活动进程打开了文件(对于日志文件来说并不罕见),则删除该文件并创建一个新文件不会影响日志记录程序。这些消息只会继续转到不再链接的文件。清空文件不会破坏关联,因此清除文件不会影响日志记录程序。
(重点是我的)
我不明白为什么程序会继续记录到已删除的文件。是因为文件描述符条目没有从过程表中删除吗?
Answers:
删除文件时,实际上是删除了指向该文件(指向inode)的链接。如果有人已经打开了该文件,则他们可以保留他们拥有的文件描述符。该文件保留在磁盘上,占用空间,并且如果您有权访问该文件,则可以对其进行读写。
该unlink
功能是由POSIX定义的:
当文件的链接计数变为0且没有进程打开文件时,应释放文件所占用的空间,并且不再可访问该文件。如果在删除最后一个链接时一个或多个进程打开了文件,则应在unlink()返回之前删除该链接,但应推迟文件内容的删除,直到关闭对该文件的所有引用为止。
由于这种行为,这条建议。守护程序将打开该文件,并且不会注意到该文件已被删除(除非它正在专门监视它,这是罕见的)。它将继续愉快地写入它具有的现有文件描述符:您将继续占用磁盘上的(更多)空间,但是您将看不到它写入的任何消息,因此您的处境实际上是最糟糕的两个世界。如果将文件截断为零长度,则空间将立即释放,并且所有新消息都将附加在文件的新末端,您可以在其中看到它们。
最终,当守护程序终止或关闭close
文件时,空间将被释放。在此期间,没有新用户可以打开文件(除非通过系统特定的反射接口(如Linux的/proc/x/fd/...
接口)打开)。还保证:
如果文件的链接计数为0,则当与该文件关联的所有文件描述符都关闭时,该文件所占用的空间将被释放,并且该文件将不再可访问。
因此,您不会永久丢失磁盘空间,但是通过删除文件不会获得任何好处,并且您无法访问新消息。
/proc/*/fd/*
是指向实际文件的符号链接,因此删除它们不会删除该文件。我建议您尝试一下:)(当然不在生产系统上!)
rm
内部无节制/proc
或/sys
不通过系统反正继续听。
究竟。
文件是三方的。
/home/user/personal_file
,它们充当句柄,您可以通过该句柄使用文件,修改文件的内容,更改其元数据等。打开文件时,您将提供操作系统的路径,它会直接向您返回到索引节点的句柄。使用称为文件描述符的此句柄,您可以根据需要(或至少在OS允许的情况下)操纵文件。
您永远不能直接删除索引节点,而必须提供操作系统路径以要求删除。因此,当您要删除文件时,仅删除目录条目。如果文件具有其他目录条目,它将继续可访问,即使没有,也不会删除它的inode,同时仍然有指向它的文件描述符。@MichaelHomer的答案在这个特定主题上更具技术性和详细性。
其他两个答案很好地说明了这个问题-在所有目录链接到该文件以及所有打开的文件描述符都消失之前,该文件不会被“删除” 。
为了避免这种情况,使用它是一个好习惯
> /var/log/bigfile
代替
rm -f /var/log/bigfile
因为那只是将内容重置为0字节而不是删除它,所以您仍然可以看到写入的内容。
如果删除了文件,并且在Linux上具有/ proc / fd文件系统,则仍可以使用
> /proc/12345/fd/3
将文件的内容清零(假设12345是您的进程ID,而3是大文件的fd号)。如果磁盘已满,并且由于某种原因您无法终止正在写入日志文件的进程,则可以节省生命。
> /var/log/bigfile
删除文件中的现有数据,但不会阻止程序在其中写入数据。在极少数情况下,这是对的。我想说这是一个坏习惯。如果要删除文件,请使用rm
。如果要停止正在此处写入的程序,请在删除之前或之后将其杀死,或以其他方式使其停止写入。
syslogd
填满而使磁盘满了/var/log/messages
,> /var/log/messages
比杀死磁盘更好的选择syslogd
。当然,这并不能阻止您首先分析问题所在。
/proc/x/fd/y
?这会导致进程无法写入文件描述符,还是非法操作?