cat /dev/null 清空了我的日志文件,但大小没有改变

cat /dev/null 清空了我的日志文件,但大小没有改变

我对 Unix 还很陌生。使用 Solaris 10 我遇到了以下问题。

有一个很大的日志文件,大小为 9.5G。我尝试使用以下命令清空文件。

# cat /dev/null file_log.txt

通过这样做,我重新获得了文件系统上的空间,但文件的大小仍然显示相同并且正在增加。我认为一个进程仍在运行到日志文件中。

有没有办法纠正文件大小?这会影响我的文件系统吗?

答案1

假设你想说

cat /dev/null > file_log.txt

或者

cp /dev/null file_log.txt

对于这个问题具有相同的效果,答案是打开文件进行写入的进程在没有 的情况下这样做O_APPEND,或者它任意设置文件的偏移量,在这种情况下稀疏文件被建造。

手册页write(2)解释得非常清楚:

对于可查找文件(即可以应用 lseek(2) 的文件,例如常规文件),写入发生在文件偏移处,并且文件偏移量按实际写入的字节数递增。如果文件是使用 O_APPEND 打开(2)的,则在写入之前首先将文件偏移量设置为文件末尾。文件偏移量的调整和写入操作作为原子步骤执行。

上述偏移量是一个属性相应的文件描述符写入过程的影响 - 如果另一个进程截断文件或将自身写入文件,这不会对偏移量产生任何影响。 (此外,如果相同进程打开文件进行写入,而不会O_APPEND为此接收不同的文件描述符,并且通过新文件描述符写入文件将具有相同的效果。)

假设这个过程打开一个文件进行写入而不附加,产生文件描述符FD。然后,一旦stat()截断文件(例如通过复制到文件)对文件大小(如报告所述)的影响将被撤消/dev/null写信给FD。具体来说,write()关于FD系统将移动(“寻找”)到与FD,用零填充从文件当前末尾(可能到开头,如果它被完全截断)到偏移量的空间。但是,如果文件变大更大同时,写信给FD将从偏移量开始覆盖文件的内容。

稀疏文件是包含“漏洞”的文件,即系统“知道”有大片带有零的区域,但这些区域并未真正写入磁盘。这就是为什么duls同意 -du查看实际磁盘使用情况,而ls仅使用stat()来提取文件大小属性。

解决方法:重新启动该进程。如果可能的话,重写打开文件的部分以使用(或使用时的O_APPEND模式)。afopen()

答案2

cat /dev/null是一个无操作,因为它什么也不输出。cp /dev/null file同样毫无意义。

清空文件内容的一种更简单的方法是将 null 命令重定向到该文件:

: > file

甚至,对于大多数 shell,仅使用重定向而不指定任何命令:

> file  

报告的大小仍然很高的事实ls只是由于写入过程在写入之前寻求文件结尾的预期想法。因为在搜索点之前没有“任何东西”,所以这应该不会造成伤害。唯一的风险是您想要使用非稀疏文件感知工具来备份或复制受影响的文件。

请注意,重新启动写入过程不会“恢复”空间,因为文件将保持“有洞”。

如果您确实希望将报告的文件大小清零,则需要在清空文件之前停止(终止)写入进程。

答案3

cat /dev/null file_log.txt

这只会让 cat 读取/dev/null并立即读取结果file_log.txt并将结果输出到stdout您的屏幕。这根本不会删除任何内容。

如果你想测试一下,使用cat /dev/null non_existent_file你会发现它出错了。

截断文件的正确方法是使用 shell 重定向器或任何类型的编辑器来删除行。你打算做的是:

cat /dev/null > file_log.txt

这是第一种方法。

相关内容