【问题标题】:interrupt linux command redirection can loss data?中断linux命令重定向会丢失数据吗?
【发布时间】:2015-09-15 03:34:53
【问题描述】:

如果我运行这样一个 bash 脚本,并且在脚本中,它会调用一些可执行的命令,比如下面的

myexec args1 arg2 > out.txt

myexec 将通过 c API printf 打印一些日志信息。如果我中断脚本,因为myexec被一些未知的原因卡住了,是否会丢失一些日志信息,而不是保存到out.txt文件中?在我的实验中,我发现它是,但有没有办法解决这个问题?而且我不知道为什么日志信息没有刷新到 out.txt 文件中

========

我用stdbuf解决了我的问题,相关问题是:Force line-buffering of stdout when piping to tee

【问题讨论】:

  • 很大程度上取决于很多因素,例如缓冲区大小、刷新频率、访问 printf 的方式,最重要的是您的程序,显示代码。
  • 是的,我知道,但我没有源代码。我真的很想知道在我中断日志时是否可以有方法来捕获日志。比如我把上面的代码包装在python fabric命令中。当我中断执行时,出现异常,我使用了一个尝试...最后将所有日志信息刷新到文件中。

标签: c linux bash


【解决方案1】:

当您中断脚本时,stdout 缓冲区很有可能没有被刷新。在您的程序中,在每个printf 之后立即添加一个fflush(stdout) 以刷新缓冲区。或者,在您的 printf 末尾添加一个换行符 (\n) - 这也会刷新缓冲区(但会在您的日志输出中添加一个换行符)。

【讨论】:

  • 谢谢!稍后我将在我的程序中使用它。但是我现在不能修改这个可执行文件,因为我不能修改源代码,我只知道它会记录一些信息。
  • 在这种情况下 - 试试这个问题的答案,这与你目前的困境有点相似:stackoverflow.com/questions/11337041/…
  • 如果 stdout 被重定向到文件,换行符不会刷新缓冲区。默认情况下会切换到块缓冲。
  • @tonysdg 谢谢,从你给的 url,我发现 stdbuf 方法有效,太棒了!
【解决方案2】:

您可以指定将正确完成您的程序的信号(SIGUSR1, SIGUSR2 等,尽管您不能覆盖 SIGKILL)。在信号处理程序中刷新您的输出流(fflush(stdout) 或替代品)并关闭应用程序。 要停止你的程序类型 smth 像

杀死 -SIGUSR1 pidof myapp

【讨论】:

  • 这绝对是更优雅的处理问题的方式。也有点复杂。
  • 在我的服务器应用程序中,我使用 fprintf(stdout,...) 编写日志,并覆盖 stdout 并且没有任何刷新。这使程序在不删除日志的情况下运行得更快。如果我确实需要阅读完整的日志 - 我使用覆盖的 SIGUSR1,它只是刷新标准输出。
  • 非常感谢!好点,但也只适用于你有源代码。
猜你喜欢
  • 2011-02-12
  • 2013-01-06
  • 1970-01-01
  • 2017-09-11
  • 2017-05-03
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多