1、如何理解重定向?
(1)关掉0之后

运行结果:

(2)close 2 之后。


所以在Linux中文件描述符的分配规则是什么呢?
分配文件描述符表中,值最小并且没有被使用的fd。


进程文件管理结构--进程文件描述表结构与标准输入输出原理
进程要使用磁盘中的文件,会先将文件加载到内存,再由CPU通过进程调度来处理这些文件;每个进程的PCB(即task_struct)中都有一个files指针,专门指向files_struct这个文件描述符表,表内的fd_array数组负责管理进程打开的所有文件,数组下标0、1、2固定对应标准输入、标准输出和标准错误,这就是进程管理文件的核心内核结构。
关闭文件描述符1后printf无法屏幕输出的原因
关闭文件描述符1后,原本指向标准输出的fd_array[1]被清空,再调用open时内核会将这个空闲的1号描述符重新分配给新文件,此时printf依然向1号描述符输出数据,却不再输出到屏幕而是写入文件,因此屏幕上看不到打印内容。
重定向的本质是:其实就是改掉数组特定的下标内的内容。
dup2使用方法
函数含义:dup2(旧fd, 新fd);
-
把旧fd 的指向,复制给 新fd
-
新fd 会被改掉,旧fd 不变
记住一句话:
谁在后面,谁被改;
前面不动,后面跟前面走。
举例
- dup2(3, 1)
-
3 → 文件
-
结果:1 也指向文件(屏幕变文件)
- dup2(1, 3)
-
1 → 屏幕
-
结果:3 也指向屏幕(原来的文件被替换)
作用
用来重定向输入/输出,让本来写给屏幕/键盘的数据,改写到文件或别的地方。

重定向的本质是:修改文件描述符的指向
程序替换不会影响进程打开的文件。
如何理解Linux下一切皆文件?

一句话总结
Linux"一切皆文件"的核心:用统一的文件接口( read / write 等)抽象所有资源,让应用层无需关心底层差异。
核心要点
-
统一抽象:将普通文件、硬件设备、进程通信、内核数据等,都抽象为文件对象,通过 struct file 提供统一的操作接口。
-
分层实现:上层是统一的 read / write 调用,下层由不同设备驱动(如 read_keyboard 、 write_screen )完成实际操作,实现"上层统一,下层各异"。
-
核心价值:简化编程、灵活组合(如重定向)、统一权限管理,让系统设计更简洁高效。
也就是说,
每个设备对应一个 struct file 结构体,结构体里的 read / write 等函数指针,会绑定到该设备驱动的具体实现;当调用通用的文件操作接口时,就会通过这些指针触发对应硬件的专属功能。
Linux "一切皆文件"的核心实现机制,其本质是通过统一抽象 + 多态分发来管理所有硬件和资源:
-
统一抽象层(基类):内核为所有打开的硬件(键盘、屏幕、网卡等)创建统一的 struct file 结构体,对外提供 read() 、 write() 等统一的文件操作接口,让应用层无需关心底层差异。
-
具体实现层(子类):每种设备都有专属的驱动函数(如 read_keyboard() 、 write_screen() ),这些函数是对底层硬件操作的具体实现,对应图中的"子类"。
-
多态分发机制: struct file 内部的函数指针会在设备初始化时,被绑定到对应设备驱动的具体实现函数上。当应用程序调用统一的 read / write 接口时,内核会通过文件描述符找到对应的 struct file ,再通过函数指针间接调用到底层驱动的专属函数,从而实现"上层统一调用,底层差异执行"的多态效果。
简单来说,就是用一套统一的"文件操作"门面,把底层硬件的差异全部封装起来,让所有资源都能像文件一样被高效、一致地管理和使用。