我在C中编写了一个程序,它使用printf将消息发送到stdout,我无法将输出重定向到文件(从bash运行)。
我试过了:
./program argument >> program.out
./program argument > program.out
./program >> program.out argument
./program > program.out argument
在每种情况下,都会创建文件program.out但它仍然为空。执行结束后,文件大小为0.
如果我在执行程序时省略了重定向:
./program argument
然后,使用printf发送到stdout的所有消息都显示在终端中。
我有其他C程序,我没有问题以这种方式重定向输出。 它与程序本身有关吗?与论点传递? 应该在哪里寻找问题?
关于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);
}
答案 0 :(得分:15)
换行后的刷新仅在打印到终端时有效,但在打印到文件时不一定。 Google快速搜索在此页面中显示了更多信息:http://www.pixelbeat.org/programming/stdio_buffering/
请参阅标题为“默认缓冲模式”的部分。
毕竟,您可能必须添加一些调用fflush(stdout)。
您还可以使用setvbuf设置缓冲区大小和行为。
答案 1 :(得分:6)
刷新缓冲区通常由exit()
函数处理,该函数通常由main()的return
隐式调用。您通过引发SIGINT结束程序,显然默认的SIGINT处理程序不会刷新缓冲区。
看看这篇文章: Applying Design Patterns to Simplify Signal Handling。这篇文章主要是C ++,但在第二部分中有一个有用的C示例,它展示了如何使用SIGINT优雅地退出程序。
至于为什么终端的行为与文件不同, 看看史蒂文斯的Advanced Programing in the UNIX Environment关于缓冲的第5.4节。他说:
大多数实现默认使用以下类型的缓冲。 标准错误始终是无缓冲的。 如果它们引用终端设备,则所有其他流都是行缓冲的;否则,它们是完全缓冲的。 本书中讨论的四个平台遵循标准I / O缓冲的这些约定:标准错误是无缓冲的,对终端设备开放的流是行缓冲的,所有其他流都是完全缓冲的。
答案 2 :(得分:3)
在检查重定向文件的内容时程序是否已终止?如果它仍然在运行,你的输出可能仍会在链的某个地方缓冲,所以你不会在文件中看到它。
除此之外,到目前为止提供的其他答案,我认为是时候展示问题代码的代表性示例了。有太多深奥的可能性。
修改强>
从示例代码的外观来看,如果您发生了相对少量的打印,那么您就会陷入输出缓冲区。每次写入后刷新,以确保它已进入磁盘。通常情况下,您可以拥有最多不同页面大小的未写入数据。
在没有同花顺的情况下,唯一可以确定你已经拥有磁盘上所有内容的时间是程序退出时。即使是一个终止的线程也不会这样做,因为像这样的输出缓冲区不是每个线程,它们是每个进程。
答案 3 :(得分:0)
建议:
答案 4 :(得分:0)
只是为了记录,在Perl中你会使用:
use IO::Handle;
flush STDOUT;
autoflush STDOUT;