我尝试了下面的代码,但屏幕什么也没显示。
close(STDOUT_FILENO);
printf("Child output something\n");
只是找不到标准输出,然后中止数据?
我想找到更多的printf写一些数据,因为我无法打印返回值,所以我将其输出到一些文件。
close(STDOUT_FILENO);
int res = printf("output something\n");
open("./log.output", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
printf("%d", res); // return 1
7```
您看到此结果的原因与缓冲有关。通常,附加到终端的文件是行缓冲的,而所有其他文件是块缓冲的。 stderr是无缓冲的。
关闭stdout时,它不再连接到终端,因此它是块缓冲的,而不是行缓冲的。您尝试写入的字节数少于缓冲区的大小(通常是512的倍数),因此很printf高兴将其复制到缓冲区中,而没有执行其他操作。如果您使用编写了适当数量的数据printf,那么您会发现它确实确实失败了。
您可以通过调用来验证类似行为fflush(stdout):
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
close(STDOUT_FILENO);
int res = printf("output something\n");
fprintf(stderr, "%d\n", res);
res = fflush(stdout);
fprintf(stderr, "%d %s\n", res, strerror(errno));
}
将输出最后一行-1 Bad file descriptor,这表明EBADF按预期方式将写入标准输出的尝试失败。如果需要验证是否已写入数据,则必须致电fflush或fsync视情况而定。
请注意,通常,您不想关闭这三个默认文件描述符中的任何一个,因为任何时候打开一个新的文件描述符,它将使用最低的未使用编号并代替标准流之一。如果程序的单独部分尝试不检查就写入这些流之一,则它可能会写入意外文件,从而损坏该文件。安全的做法是将这些流重定向到/dev/null。
您的open要求log.output与我刚才提到的事情完全相同,它再次打开了文件描述符1(stdout)。
分享改善这个答案
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。