我dup2
在尝试将两者都重定向stdout
到stderr
同一个输出文件时遇到了一些麻烦。
我正在使用这个解释性代码示例:(gcc 4.8.2,Ubuntu 14.04)
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#define USE2FILES
int main()
{
int f1, f2, status;
f1 = open("test.out", O_CREAT | O_WRONLY, 0644);
if (f1 == -1) {
perror("open(): ");
}
status = dup2(f1, STDOUT_FILENO);
if (status == -1) {
perror("dup2(): ");
}
#ifdef USE2FILES
close(f1);
#endif
#ifdef USE2FILES
f2 = open("test.out", O_CREAT | O_WRONLY, 0644);
if (f2 == -1) {
perror("dup2(): ");
}
#else
f2 = f1;
#endif
status = dup2(f2, STDERR_FILENO);
if (status == -1) {
perror("dup2(): ");
}
close(f2);
fprintf(stderr, "test_stderr1\n");
fprintf(stdout, "test_stdout1\n");
fprintf(stderr, "test_stderr2\n");
fprintf(stdout, "test_stdout2\n");
fprintf(stderr, "test_stderr3\n");
fprintf(stdout, "test_stdout3\n");
fflush(stdout);
fflush(stderr);
return 0;
}
USE2FILES 宏应该在使用 2 个文件描述符(到同一个文件)之间切换,它们分别被复制到stdout
和stderr
或 1 个文件描述符被复制到stdout
和stderr
.
我的印象是使用 2 个不同的文件描述符进行重定向应该可以工作。但是,使用 USE2FILES 运行这段代码会在以下输出test.out
:
test_stdout1
test_stdout2
test_stdout3
如果我然后禁用 USE2FILES 我得到:
test_stderr1
test_stderr2
test_stderr3
test_stdout1
test_stdout2
test_stdout3
似乎在第一种情况下没有输出stderr
通过。这种行为是否可以预料(我错过了什么)?
编辑:接受克里斯多德的回答后:这确实是一个糟糕的例子。将序列更改为fprintf
如下所示:
fprintf(stderr, "test_stderr+++++++++++++++++++++++++++++++++++++++++++++++++1\n");
fprintf(stdout, "test_stdout----------------------------------------1\n");
fprintf(stderr, "test_stderr++++++++++++++++++++++++++++++++++2\n");
fprintf(stdout, "test_stdout----------------2\n");
fprintf(stderr, "test_stderr++++++++++++++++++++++++++++3\n");
fprintf(stdout, "test_stdout----------------------3\n");
得到我这个test.out
输出:
test_stdout----------------------------------------1
test_stdout----------------2
test_stdout----------------------3
err++++++++++++++++++++++++++++3
显示得很清楚stdout
,stderr
并且正在与他们在同一个文件上的写入竞争。