关于stderr与stdout的重定向问题

时间:2022-12-02 00:01:47
  1 #include<stdio.h>
  2 int main(void)
  3 {
  4     fprintf(stdout, "111\n");
  5     fprintf(stderr, "aaa\n");
  6 
  7     return 0;
  8 }



这样的代码在重定向的时候用./a.out >file 2>&1  为什么文件file中总是先显示aaa?是跟优先级有关系么?

5 个解决方案

#1


是因为stderr是立即刷新缓冲的原因, 你在两句fprintf中加一句  fflush(stdout); 就明白了

#2


重定义到文件后,,标准输出就变成全缓冲(而不是行缓冲)
所以即使后面有个"\n"换行符,stdout也不会刷新缓冲,得等到缓冲区满(一般8192B)才会实际写入
或者调用fflush(stdout)强制刷新缓存,使其写入

而stderr不管怎么样重定向,都是无缓存,向其输入数据后,马上实际写入。

#3


引用 1 楼  的回复:
是因为stderr是立即刷新缓冲的原因, 你在两句fprintf中加一句  fflush(stdout); 就明白了
恩  明白了哈  谢谢

#4


引用 2 楼  的回复:
重定义到文件后,,标准输出就变成全缓冲(而不是行缓冲)
所以即使后面有个"\n"换行符,stdout也不会刷新缓冲,得等到缓冲区满(一般8192B)才会实际写入
或者调用fflush(stdout)强制刷新缓存,使其写入

而stderr不管怎么样重定向,都是无缓存,向其输入数据后,马上实际写入。
明白了  谢谢哈

#5


要解释的话只能按照fdl19981所说的来理解了。

我本以为shell只是fork,open,dup2将1和2重定向,exec的子进程是对fd到底指向什么设备不关心的,看样glibc还是会判断一下0和1关联的设备来决定FILE *stdout/*stderr的缓冲方式。

#1


是因为stderr是立即刷新缓冲的原因, 你在两句fprintf中加一句  fflush(stdout); 就明白了

#2


重定义到文件后,,标准输出就变成全缓冲(而不是行缓冲)
所以即使后面有个"\n"换行符,stdout也不会刷新缓冲,得等到缓冲区满(一般8192B)才会实际写入
或者调用fflush(stdout)强制刷新缓存,使其写入

而stderr不管怎么样重定向,都是无缓存,向其输入数据后,马上实际写入。

#3


引用 1 楼  的回复:
是因为stderr是立即刷新缓冲的原因, 你在两句fprintf中加一句  fflush(stdout); 就明白了
恩  明白了哈  谢谢

#4


引用 2 楼  的回复:
重定义到文件后,,标准输出就变成全缓冲(而不是行缓冲)
所以即使后面有个"\n"换行符,stdout也不会刷新缓冲,得等到缓冲区满(一般8192B)才会实际写入
或者调用fflush(stdout)强制刷新缓存,使其写入

而stderr不管怎么样重定向,都是无缓存,向其输入数据后,马上实际写入。
明白了  谢谢哈

#5


要解释的话只能按照fdl19981所说的来理解了。

我本以为shell只是fork,open,dup2将1和2重定向,exec的子进程是对fd到底指向什么设备不关心的,看样glibc还是会判断一下0和1关联的设备来决定FILE *stdout/*stderr的缓冲方式。