C 使用dup2将stdout/stderr重定向到同一文件时出现问题
在尝试将C 使用dup2将stdout/stderr重定向到同一文件时出现问题,c,linux,dup2,C,Linux,Dup2,在尝试将stdout和stderr重定向到同一输出文件时,使用dup2遇到一些问题 我正在使用这个解释性代码示例:(GCC4.8.2,Ubuntu 14.04) 如果禁用Use2文件,我会得到: test_stderr1 test_stderr2 test_stderr3 test_stdout1 test_stdout2 test_stdout3 似乎在第一种情况下,stderr的输出没有通过。这种行为是意料之中的吗(我是否遗漏了什么) 编辑:接受Chris Dodd的回答后: 这确实是一个
stdout
和stderr
重定向到同一输出文件时,使用dup2
遇到一些问题
我正在使用这个解释性代码示例:(GCC4.8.2,Ubuntu 14.04)
如果禁用Use2文件,我会得到:
test_stderr1
test_stderr2
test_stderr3
test_stdout1
test_stdout2
test_stdout3
似乎在第一种情况下,stderr
的输出没有通过。这种行为是意料之中的吗(我是否遗漏了什么)
编辑:接受Chris Dodd的回答后:
这确实是一个糟糕的例子。将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
与它们对同一文件的写入竞争。如果执行两个open
调用,您会得到两个不同的内核文件句柄,每个句柄都有自己的I/O游标(文件偏移量),因此对两个文件描述符的写入将相互覆盖。如果使用单个open
调用,则只会得到两个文件描述符都引用的单个文件句柄,因此每次写入(到每个描述符)都会使输出偏移量提前,以便下一次写入(使用另一个文件描述符)会在其后写入
在您的示例中,写入的字符串长度完全相同,因此写入stdout
将完全覆盖前面写入stderr
。请注意,文件写入仅在刷新文件
对象时发生,而在调用fprintf
时(不一定)发生
您还可以通过在
O_APPEND
模式下打开文件来获得您想要的效果。这将导致每次写入操作在实际写入之前将写入偏移量重新定位到文件的当前端。如果执行两次open
调用,将得到两个不同的内核文件句柄,每个内核文件句柄都有自己的I/O游标(文件偏移量),因此对两个文件描述符的写入操作将相互覆盖。如果使用单个open
调用,则只会得到两个文件描述符都引用的单个文件句柄,因此每次写入(到每个描述符)都会使输出偏移量提前,以便下一次写入(使用另一个文件描述符)会在其后写入
在您的示例中,写入的字符串长度完全相同,因此写入stdout
将完全覆盖前面写入stderr
。请注意,文件写入仅在刷新文件
对象时发生,而在调用fprintf
时(不一定)发生
您还可以通过在O_APPEND
模式下打开文件来获得您想要的效果。这将导致每次写入在实际写入之前将写入偏移量重新定位到文件的当前端
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_stdout----------------------------------------1
test_stdout----------------2
test_stdout----------------------3
err++++++++++++++++++++++++++++3