如何截断重定向的流输出?

如何截断重定向的流输出?

我有一个过程,每次进度更新都会输出一行(旁注:它会清除/替换该行,没有纯粹的换行符)。

我想将该过程的最新行保存到输出文件或截断输出文件以保持大小易于管理。

目前我有 genrtr > genrtr.log 一个 cron,我尝试使用它> genrtr.log,但它不起作用。而且rm genrtr.log没有帮助,因为进程会停止更新文件。

我明白为什么它们不起作用,但想知道如何重组它以满足我的需要。

已尝试genrtr | sed -ne '$w genrtr.log',但它要等待进程结束后才写入文件。

澄清:该过程每秒产生一次输出,除非服务器崩溃,否则该过程将永远运行。

答案1

我想知道运行的频率是多少?....

尝试使用 tee 将输出重定向到日志文件,它是一种实用程序,通常用于复制 strem 并将该副本重定向到输出文件

use : 
  command | tee command_result.log 

你可以在包装脚本中添加一个监视函数,该函数调用该程序,经过一段时间后删除前 10 行……这样你的日志文件就不会超过几 KB

此外,如果中间有无用的空格,您可以使用翻译“tr”实用程序来压缩...例如:

Nitin@Kaizen ~
$ df -h | head -1
    Filesystem      Size  Used Avail Use% Mounted on

Nitin@Kaizen ~
$ df -h | head -1 | tr -s ' '
    Filesystem Size Used Avail Use% Mounted on   *** note the squeeze in space 

希望这可以帮助

答案2

您可以尝试以下几种方法。最简单的方法是只打印文件的最后几行:

tail genrtr.log

然后,一旦该过程完成,删除日志文件。另一个选择是定期覆盖该文件。

  • 在后台启动该进程:

    genrtr > genrtr.log &
    
  • 覆盖日志文件的内容:

    echo > genrtr.log
    

该文件现在已被截断,但将继续更新,gentr因此下一个更新报告将写入该文件。您可以自动执行此操作,例如,如果文件大于 1MB,则截断文件:

while true; 
  do if [ $(stat -c%s genrtr.log) -gt 1000000 ]; then 
    tail genrt.log > /tmp/foo && cat /tmp/foo > genrt.log; 
     fi;
done

这个小脚本会一直运行直到你停止它(while true;),并且每次 genrtr.log 大于 1 MB 时,它都会保留最后几行并删除文件的其余部分。


更新:

正如 Scott 在下面非常正确地指出的那样,如果您的输出包含\r清除行,tail则不会按预期工作。但是,这应该:

while true; 
  do if [ $(stat -c%s genrtr.log) -gt 1000000 ]; then 
    tail genrt.log | perl -pe 's/.+\r(.+)/$1\n/' > /tmp/foo && cat /tmp/foo > genrt.log; 
     fi;
done

perl 命令删除最后一个之前的所有内容\r并打印最后一“行”(和换行符之后的数据\r。结果应该是列表行被保留,文件的其余部分被清除并且文件继续填充。

答案3

我相信如果不修改或编写新程序,这将非常棘手genrtrc 。如果您更愿意做后者,我建议您遵循以下大纲:

int   c;
FILE  *fp;

fp = fopen(日志档案, "w");
if (fp == NULL) (处理错误)
while ((c = getc()) != EOF)
{
    putchar(c);
    if (c ==结束一行的转义序列)
    {
        fflush(fp);     //您可能也应该在这里检查错误。
        rewind(fp);
    }
    else
        putc(c, fp);
}

这就像tee和的组合tail——读取标准输入,并将其写入标准输出和文件——不同之处在于它只保留文件中的最后一行。然后你可以运行

genrtr |上述程序

答案4

解决方案

目前我有genrtr > genrtr.log一个 cron,我尝试过使用它> genrtr.log,但是它不起作用。

genrtr >> …可以使用而不是 来轻松修复此方法genrtr > …(同时仍在>cron 中使用来截断文件)。

差异解释如下这是我的另一个答案可以用以下陈述来总结:

>>本质上是“始终寻找文件末尾”,同时>保持指向最后写入位置的指针。

阅读链接的答案,它完全符合您的情况。


边注

rm genrtr.log无济于事,因为该过程会停止更新文件。

严格来说才不是停止更新文件。文件从目录中取消链接,但仍处于打开状态,仍写给,它仍然会消耗文件系统中越来越多的空间。

任何新文件都是不同的文件,即使它采用相同的路径名。进程不会更新新文件,因为它永远不会打开它,甚至不会注意到它。进程使用的文件描述符仍然指向旧(已删除)文件。

相关内容