我尝试了下面的代码,但屏幕上什么也没有显示。
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可以工作,但我不知道它写到哪里。
发布于 2019-11-29 05:14:43
您看到此结果的原因与缓冲有关。通常,连接到终端的文件是行缓冲的,而所有其他文件都是块缓冲的。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
。
对log.output
的open
调用恰好完成了我刚才提到的事情,即再次打开文件描述符1 (stdout)。
https://stackoverflow.com/questions/59094054
复制相似问题