我编写了一个程序在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程序的一些细节:
一些代码:
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缓冲:标准错误是无缓冲的,向终端设备开放的流是行缓冲的,其他所有流都是完全缓冲的。
程序在检查重定向文件的内容时是否终止? 如果它仍然在运行,你的输出可能仍然被缓冲在链上,所以你不会在文件中看到它。
除此之外,还有迄今为止提供的其他答案,我认为是时候展示问题代码的代表性例子了。 有太多的深奥的可能性。
编辑
从示例代码的外观来看,如果发生的打印数量相对较少,则会被捕获到输出缓冲区中。 在每次写入之后冲洗以确保它已经写入磁盘。 通常情况下,您最多可以拥有一个页面大小的不成文数据。
在没有刷新的情况下,只有当磁盘上有所有东西时, 程序才会退出。 即使是一个线程终止也不会这样做,因为这样的输出缓冲区不是每个线程,而是每个进程。
建议:
只是为了记录,在Perl中你可以使用:
use IO::Handle; flush STDOUT; autoflush STDOUT;