use*_*960 4 logs io-redirection files cat
我对Unix很陌生。使用 Solaris 10 我遇到了以下问题。
有一个大小为 9.5G 的大日志文件。我尝试使用以下命令清空文件。
# cat /dev/null file_log.txt
Run Code Online (Sandbox Code Playgroud)
通过这样做,我重新获得了文件系统上的空间,但文件的大小仍然显示相同并且还在增加。我认为一个进程仍在运行到日志文件中。
有没有办法纠正文件大小?这会影响我的文件系统吗?
cou*_*ode 18
假设你想说
cat /dev/null > file_log.txt
Run Code Online (Sandbox Code Playgroud)
或者
cp /dev/null file_log.txt
Run Code Online (Sandbox Code Playgroud)
这对此事具有相同的效果,答案是打开文件进行写入的进程没有这样做O_APPEND,或者它任意设置文件的偏移量,在这种情况下会创建一个稀疏文件。
手册页write(2)解释得很清楚:
对于可查找文件(即,可以应用 lseek(2) 的文件,例如,常规文件)写入发生在文件偏移量处,并且文件偏移量按实际写入的字节数递增。如果文件是用 O_APPEND 打开 (2) 的,则在写入之前首先将文件偏移量设置为文件的末尾。文件偏移的调整和写操作是作为一个原子步骤执行的。
所述偏移量是写入进程的相应文件描述符的属性- 如果另一个进程截断文件或将自身写入文件,则这不会对偏移量产生任何影响。(此外,如果同一个进程打开文件进行写入而没有O_APPEND它会收到不同的文件描述符,并且通过新的文件描述符写入文件将具有相同的效果。)
假设进程P打开一个文件进行写入而不附加,产生文件描述符fd。然后,一旦P写入fdstat(),截断文件(例如通过复制/dev/null到它)对文件大小(如报告)的影响将被撤消。具体地说,在到的fd系统将移动(“查找”)与相关的偏移量的fd,从文件的当前端填充所述空间(可能开始时,如果它被完全截断)到用零偏移。但是,如果文件同时变大,写入fd将覆盖文件的内容,从偏移量开始。write()
稀疏文件是包含“空洞”的文件,即系统“知道”存在带有零的大区域,这些区域并未真正写入磁盘。这就是为什么du与ls分歧-du着眼于实际的磁盘使用情况,同时ls使用简单stat()解压文件的大小属性。
解决方法:重新启动进程。如果可能,重写打开文件的部分以使用O_APPEND(或使用a时的模式fopen())。
jll*_*gre 10
cat /dev/null是一个无操作,因为它什么都不输出。cp /dev/null file同样毫无意义。
一种更简单的清空文件内容的方法是将 null 命令重定向到它:
: > file
Run Code Online (Sandbox Code Playgroud)
甚至,对于大多数 shell,只使用重定向而不指定任何命令:
> file
Run Code Online (Sandbox Code Playgroud)
报告的大小ls仍然很高的事实只是由于写入过程在写入之前寻求其预期的文件末尾应该是什么。因为在搜索点之前没有“空”,所以这不应该受到伤害。唯一的风险是您想要使用非稀疏文件感知工具备份或复制受影响的文件。
请注意,重新启动写入过程不会“恢复”空间,因为文件将保持“有洞”。
如果您确实希望将报告的文件大小归零,则需要在清空文件之前停止(终止)写入过程。