C语言write()函数文件描述符传0,为什么还是会写入到标准输出(屏幕上)
write的声明如下
ssize_t write(int fd, const void *buf, size_t count);
可以看到第一个参数应该是文件描述符(windows下叫句柄),然后通常情况下,进程会将0初始化为标准输入,将1初始化为标准输出
# define stdin 0
# define stdout 1
但是不知道为什么write这个函数的行为似乎有些诡异,我做了这样一个实验
#include <unistd.h>
#include <string.h>
int main() {
char *message1 = "Writing to stdout using file descriptor 0\n";
char *message2 = "Writing to stdout using file descriptor 1\n";
write(0, message1, strlen(message1));
write(1, message2, strlen(message2));
return 0;
}
正常来讲我感觉write函数应该只有message2是可以正常打印的,message1理论上来说会报错,
因为理论上来讲write函数应该是无法写入0(stdin)的, 可是程序编译和运行却完全没有任何问题,这是运行结果
$ gcc test.c
$ ./a.out
Writing to stdout using file descriptor 0
Writing to stdout using file descriptor 1
所以我想问一下有没有大佬知道为什么write函数文件描述符传0也会写入标准输出(stdout)
备注:我的平台是ubuntu 22.04,gcc版本是gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
1.write函数属于linux提供的系统调用,这个函数是没有缓冲区的,直接写到fd对应文件在内存中的文件结构体中的缓冲区。
2.文件结构体维护着一个缓冲区,由操作系统决定何时将此缓冲区的内容写到文件在内存的拷贝。
3.键盘也是一个文件,不过大多数情况对于操作系统而言是一个只读文件,我们输入的本质上时字符串,先存在文件结构体的缓冲区,再由操作系统决定何时将这串字符串读到进程里面。
3.stdin=0,当尝试往stdin里面写入字符串时,实际上这个字符串先保存在键盘文件缓冲区,而键盘接收不了字符串,于是这段字符停在缓冲区,而操作系统会认为这是键盘输入的字符,打印在屏幕上。
如下图
在sleep的10s内,我在键盘上输入字符,命令行也会打印我输入的东西。