在bash中redirectC程序输出的问题

我编写了一个程序在C中使用printf发送消息到标准输出,我有麻烦redirect到一个文件(从bash运行)的文件。

我试过了:

./program argument >> program.out ./program argument > program.out ./program >> program.out argument ./program > program.out argument 

在每种情况下,都会创build文件program.out,但它仍为空。 执行结束后,文件大小为0。

如果我在执行程序时忽略了redirect:

 ./program argument 

然后,使用printf发送到stdout的所有消息都显示在terminal中。

我有其他的C程序,我没有这样redirect输出的问题。 这是否与程序本身有关? 有争论传递? 哪里应该找问题?

关于C程序的一些细节:

  • 它不会从标准input读取任何内容
  • 它使用BSD Internet域套接字
  • 它使用POSIX线程
  • 它使用sigaction为SIGINT信号分配一个特殊的处理函数
  • 它发送大量换行符到标准输出(对于那些你认为我应该冲洗)

一些代码:

 int main(int argc, char** argv) { printf("Execution started\n"); do { /* lots of printf here */ } while (1); /* Code never reached */ pthread_exit(EXIT_SUCCESS); } 

在换行之后刷新只在打印到终端时起作用,但不一定在打印到文件时起作用。 快速谷歌搜索显示此页面进一步的信息: http : //www.pixelbeat.org/programming/stdio_buffering/

请参阅“默认缓冲模式”一节。

毕竟,您可能必须添加一些调用fflush(stdout)。

您也可以使用setvbuf设置缓冲区大小和行为。

刷新缓冲区通常由exit()函数处理,通常由main() return隐式地调用。 通过提出SIGINT来结束程序,显然缺省的SIGINT处理程序不会刷新缓冲区。

看看这篇文章: 应用设计模式来简化信号处理 。 文章主要是C ++,但在第二部分有一个有用的C例子,它展示了如何使用SIGINT来优雅地退出程序。

至于为什么终端的行为与文件不同,请查看Stevens 在UNIX环境下关于缓冲的高级编程 。 他说:

大多数实现默认为以下类型的缓冲。 标准错误总是无缓冲的。 如果所有其他流都涉及终端设备,则所有其他流都是行缓冲的; 否则,它们被完全缓冲。 本书中讨论的四种平台遵循以下惯例用于标准I / O缓冲:标准错误是无缓冲的,向终端设备开放的流是行缓冲的,其他所有流都是完全缓冲的。

程序在检查重定向文件的内容时是否终止? 如果它仍然在运行,你的输出可能仍然被缓冲在链上,所以你不会在文件中看到它。

除此之外,还有迄今为止提供的其他答案,我认为是时候展示问题代码的代表性例子了。 有太多的深奥的可能性。

编辑

从示例代码的外观来看,如果发生的打印数量相对较少,则会被捕获到输出缓冲区中。 在每次写入之后冲洗以确保它已经写入磁盘。 通常情况下,您最多可以拥有一个页面大小的不成文数据。

在没有刷新的情况下,只有当磁盘上有所有东西时, 程序才会退出。 即使是一个线程终止也不会这样做,因为这样的输出缓冲区不是每个线程,而是每个进程。

建议:

  1. 将stderr重定向到一个文件。
  2. 尝试尾巴 – 你的输出文件。
  3. 打开一个文件和fprintf你的日志(以帮助弄清楚发生了什么)。
  4. 搜索std * FILE句柄或1-3个文件描述符的任何手动关闭/复制/管道。
  5. 降低复杂性; 裁剪大块的功能,直到printfs工作。 然后阅读,直到它再次破坏。 继续,直到找出罪魁祸首的代码。

只是为了记录,在Perl中你可以使用:

 use IO::Handle; flush STDOUT; autoflush STDOUT;