我试过下面的代码,但屏幕什么也没显示。
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 17
所以 printf 工作,但我不知道它写到哪里。
最佳答案
您看到此结果的原因与缓冲有关。通常,附加到终端的文件是行缓冲的,所有其他文件是 block 缓冲的。 stderr
是无缓冲的。
当您关闭标准输出时,它不再连接到终端,因此它是 block 缓冲的,而不是行缓冲的。您试图写入比缓冲区大小(通常是 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
,这表明写入 stdout 的尝试如预期的那样因 EBADF
而失败。如果您需要验证数据是否已写入,则必须根据需要调用 fflush
或 fsync
。
请注意,一般来说,您不想关闭三个默认文件描述符中的任何一个,因为任何时候您打开一个新的文件描述符,它都会使用最低的未使用数并取代其中一个标准流.如果您的程序的一个单独部分试图在不检查的情况下写入其中一个流,它可能会写入一个意外的文件,从而破坏它。安全的做法是将这些流重定向到 /dev/null
。
您对 log.output
的 open
调用与我刚才提到的完全相同,它再次打开文件描述符 1 (stdout)。
关于c - 关闭标准输出后调用 printf 会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59094054/