C -如何清空一个文件时,一个进程正在不断写入它



我的场景如下:

一个名为a.out的程序在一个无限循环中连续写入"hello world",并将其输出重定向到文件名test.log。

我想清空(截断)test.log,而a.o out不断写入test.log

您无法在不停止程序的情况下停止您描述的重新填充文件的程序。你可以用kill -STOP $(pgrep yourprogram)(之后再用kill -CONT)或者直接把它吹走。

要截断文件,

$ truncate -ssize file

,其中size是与其当前大小相当接近的任何东西。HFS+显然不会做稀疏分配,但其他所有现代都会。

(编辑2:对dd的一点测试表明,指定-s0可能很好地工作,如果您倾向于尝试)。

查看实际用于存储文件的空间,du -h file ls将报告其表观大小。

(编辑:Arch wiki条目使我对创建稀疏文件的主题有所了解)

我看到的习语是

> filename

试一下,应该能行

#include <stdio.h>
int main()
{
   FILE * pFile;
   char buffer [100];
   pFile = fopen ("myfile.txt" , "w");
   if (pFile == NULL)
       perror ("Error opening file");
   else
     fclose (pFile);
    while(1) {
        pFile = fopen ("myfile.txt" , "a");
        fputs("Hello Worldn", pFile);
        fclose (pFile);
   }
   return 0;
}

可以使用

清除文件
$echo a > myfile.txt

如果程序一直打开test.log文件,这是不容易的。无论其他进程在做什么,该进程都有一个打开的文件描述符。

您可以尝试在其他程序中执行一些ftruncate(2)。

您应该考虑使用syslog(3)设施。

这很容易。使用此命令清空test.log:

gdb -batch-silent -p `pidof a.out` -ex "call ftruncate(1,0)" -ex "call lseek(1,0,0)"  
一些解释:

  • pidof a.out返回a.out进程的PID。
  • 你说你重定向输出到文件。这就是为什么我用1作为ftruncatelseek调用中文件描述符的个数
  • ftruncate -截断一个文件到指定的长度
  • lseek -重新定位读/写文件偏移

下面是命令seq 1 1000000000 > seq.txt的示例:

$ ls -l seq.txt && gdb -batch-silent -p `pidof seq` -ex "call (void)ftruncate(1,0)" -ex "call lseek(1,0,0)" && ls -l seq.txt
-rw-r--r-- 1 user unix_users 706019328 Jun 10 09:58 seq.txt
-rw-r--r-- 1 user unix_users 65536 Jun 10 09:58 seq.txt

最新更新