Linux C中如何实现标准输出实时重定向至文件?
解决C程序日志实时写入文件的问题
问题根源
标准输出stdout的缓冲策略会根据输出目标变化:
- 输出到终端时,默认是行缓冲,遇到换行符就会刷新缓冲区;
- 输出重定向到文件时,会切换为全缓冲,只有缓冲区填满(通常4KB/8KB)或程序退出时,才会将缓冲区内容写入文件。
你的hello程序在无限循环时不会退出,缓冲区无法自动刷新,日志一直停留在内存里,tail -f看不到内容;而for循环测试时,程序10秒后退出,系统自动刷新缓冲区,因此能看到日志。
解决方法
方法1:每次输出后手动刷新缓冲区
修改hello.c,在printf后调用fflush(stdout)强制刷新缓冲区:
#include <stdio.h> #include <unistd.h> int main(){ while(1){ printf("Hello World\n"); fflush(stdout); // 强制将缓冲区内容写入文件 sleep(1); } return 0; }
方法2:设置标准输出为行缓冲
在程序启动时,通过setvbuf将stdout设置为行缓冲模式,无论输出到终端还是文件,遇到换行符都会自动刷新:
#include <stdio.h> #include <unistd.h> int main(){ // 设置stdout为行缓冲:参数依次为目标流、缓冲区(NULL用系统默认)、缓冲模式、缓冲区大小 setvbuf(stdout, NULL, _IOLBF, 0); while(1){ printf("Hello World\n"); sleep(1); } return 0; }
方法3:通过执行环境修改缓冲行为(无需修改hello.c)
如果不想修改hello的代码,可以在helloExec.c中调用程序时,使用stdbuf工具强制设置行缓冲:
修改helloExec.c的cmd数组:
char *cmd[] = {"/usr/bin/stdbuf", "-oL", "./hello", NULL};
-oL参数表示将标准输出设置为行缓冲,即使输出到文件也会实时写入。
验证效果
编译修改后的代码后,运行./helloExec,再用tail -f log.out跟踪日志,就能每秒看到一条Hello World记录了。
内容的提问来源于stack exchange,提问作者Devidas
相关产品推荐
相关产品推荐

