我尝试将stdout
和stderr
重定向到带有C程序的单个文件。
这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int redirectOutputs();
int main()
{
redirectOutputs();
printf("OUT : test\n");
perror("ERR : test");
printf("OUT : test 2\n");
int t = 23;
printf("OUT : again\n");
perror("ERR : again");
}
int redirectOutputs()
{
int log = open("err.log", O_RDWR|O_CREAT|O_APPEND, 0600);
if (log == -1)
{
perror("opening err.log");
return -1;
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
dup2(log, STDOUT_FILENO);
dup2(log, STDERR_FILENO);
close(log);
}
输出文件:
ERR : test: Success
ERR : again: Success
OUT : test
OUT : test 2
OUT : again
它们都被重定向得很好,但似乎全部stderr
被写入,然后是全部stdout
。
我想保留文件中的消息顺序。
我应该有以下文件:
OUT : test
ERR : test: Success
OUT : test 2
OUT : again
ERR : again: Success
你知道我的代码中有什么问题吗?
答案 0 :(得分:4)
问题是stdout
的输出是缓冲,而stderr
无缓冲。
您必须使stdout
无缓冲,例如stderr
,或将stderr
缓存为stdout
。您可以使用setvbuf
设置缓冲和模式。
每次输出后,您也可以在stdout
上致电fflush
。
答案 1 :(得分:3)
您的问题是缓冲。最简单的解决方案是在每次输出后调用fflush()
。您当然可以使用setvbuf()
将缓冲设置为行缓冲。
也就是说,拥有一个显式日志记录界面可能更好一点,它也可以选择性地捕获stderr
和stdout
。最后一句话,您的部分close()
来电是多余的,dup2()
会在复制之前自动关闭新的fd。