开发者社区> 问答> 正文

关闭标准输出后调用printf会发生什么?

我尝试了下面的代码,但屏幕什么也没显示。

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```

展开
收起
祖安文状元 2020-01-16 16:45:50 1010 0
1 条回答
写回答
取消 提交回答
  • 您看到此结果的原因与缓冲有关。通常,附加到终端的文件是行缓冲的,而所有其他文件是块缓冲的。 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)。

    分享改善这个答案

    2020-01-16 16:46:08
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载