当前位置: 首页 > ai >正文

Linux重定向的理解

目录

1.task_struct和struct file的关联

2.file

3.文件描述符下标的分配规则以及输出重定向的实现


1.task_struct和struct file的关联

        我们的操作系统为了管理进程,用PCB来描述进程的属性,用双链表把进程之间进行关联实现了对进程的管理,那么我们为了管理进程打开的文件,我们的进程里就有一个数组,里面存储的是struct file的指针,我们被进程打开的文件,我们通过数组下标就可以找到这个进程中对应的文件了,同样的我们描述文件用struct file,管理文件还是双链表,我们所有的进程打开的文件被双链表统一管理。这样局部每个进程都管理了它打开的文件,整体上操作系统也通过链表管理了全部被打开的文件。

得出结论:我们的文件描述符本质就是文件描述符表的下标,进程打开时会默认打开三个文件,它们分别是stdin,stdout,stderr,每个被打开的文件都有一个file,然后进程有一个数组统一指向每个文件的file,这样通过下标我们就可以知道文件在进程的位置了。

我们还会发现我们调open这样的系统接口返回的是int,这个int就是文件在进程的数组的下标,但是我们调fopen这种C语言被封装好的接口,我们返回的FILE,那么file是对文件的描述,那么我的FILE也是由标准库提供的一个结构体。我们也可以推测,这个FILE里面一定封装了int fd,因为我们要通过fd找到文件啊!本质C接口底层还是要调系统调用。

下面给一段Linux内的源码实现来佐证我们的所说!

2.file

        我们的file,我们需要知道当我们往文件里写数据时,它不是直接直接把我们的数据直接写入到磁盘,因为磁盘的速度是非常慢的,试想,我们write一个helloworld它就要进行一次写入,这样大量频繁的写入会降低我们的效率,我们不希望这样的事情发生,所以我们在file里面定义了一个文件缓冲区,当我们往文件里写数据时,实际上数据是先存到文件缓存区内的,然后由操作系统决定什么时候写入到磁盘里去。

实际上,我们对文件进行增删查改,都要先写到文件缓冲区里,不然大量频繁的与磁盘进行交流会降低我们的效率,所以我们的write根本就不是什么把数据写入到文件,而是把我们的用户空间的数据拷贝到文件的文件内核缓冲区内!!!

3.文件描述符下标的分配规则以及输出重定向的实现

        我们文件被进程打开,这个文件的存储在哪里,是存储在最小的下标里去的,从文件描述符表中寻找一个最小的,未被使用的下标,作为文件的fd。

知道了这个规则,我们就可以进行重定向的实现了,当我们关闭我们的stdin,然后打开我们的一个文件,然后printf就会往我们下标为1的文件里打印,这样就实现了输出重定向,相当于欺骗了操作系统!!!

c ? ?                                                                                                                                                                                       ?? buffers 1 #include<stdio.h>2 #include<stdlib.h>3 #include <sys/stat.h>  // 定义文件权限宏(如 S_IRUSR)4 5 #include <fcntl.h>6 #include <unistd.h>7 #include <string.h>8 int main()9 {10   close(1);
W> 11   int d=open("test.c",O_CREAT | O_RDWR | O_TRUNC,0666);                                                                                                                                                    12   printf("大帅哥是我!!!");13 14 15 16 17   return 0;18 }~~

我们这样就实现了往屏幕上打印往文件打印,这样我们就实现了重定向,那么我们的追加重定向不就是换了一个选项吗?我们的这个选项是覆盖的打印,那么我们换成append选项不就变成了追加重定向了吗?

还有一个函数dup()来帮助我们实现重定向,它是把oldfd重定向到newfd中。这样往newfd中写东西就变成了往oldfd中写东西完成了重定向!!!

这段代码的意思就是把fd重定向到1,这样往1中输入就变成了往fd中输入,这样就完成了重定向。

所以当我们理解了重定向的本质之后,那么我们创建子进程,子进程是如何看待父进程打开的文件的?

如果我们做exec程序替换,不会创建新进程那么会影响我们历史打开的文件吗?

当然不会,我们知道了我们的程序替换是对代码和数据的替换,但是进程还是那个进程,它并不影响我们的管理file的数组,所以我们进行程序替换不影响我们的进程打开文件。

而且当我们创建一个子进程,那么它会和父进程的打开文件一样的,我们打印都是往同一个文件里进行打印!!!所以只要父进程打开的012,那么子进程进行指针的拷贝也相当于打开了012!!!,

我们的task_struct和file还有属性代码和数据的关系就这样自然而然的出来了!!!

        

http://www.xdnf.cn/news/16499.html

相关文章:

  • Mysql缓冲池和LRU
  • 树形结构递归查询与嵌套结构转换:Flask + PostgreSQL 完整实现
  • Linux 启动流程、密码破解、引导修复完全手册
  • MoR vs MoE架构对比:更少参数、更快推理的大模型新选择
  • vue面试题
  • AI驱动的知识管理新时代:释放组织潜力的关键武器
  • Python Flask: Windows 2022 server SMB账户(共享盘账户)密码修改
  • Java注解全面解析与应用实战
  • 在Word和WPS文字中把全角数字全部改为半角
  • 微信小程序无法构建npm,可能是如下几个原因
  • uniapp 微信小程序 列表点击分享 不同的信息
  • 计算机视觉-图像基础处理
  • 一步步详解使用 Flask 连接数据库进行增删改查操作
  • 【PHP】几种免费的通过IP获取IP所在地理位置的接口(免费API接口)
  • 硬件学习笔记--73 电能表新旧精度等级对应关系
  • Android 解决键盘遮挡输入框
  • Javaweb————HTTP请求头属性讲解
  • 前端css 的固定布局,流式布局,弹性布局,自适应布局,响应式布局
  • VNC和RPC加固措施
  • win10 环境删除文件提示文件被使用无法删除怎么办?
  • 海外短剧系统架构设计:从0到1搭建高并发微服务平台
  • 白玩 一 记录retrofit+okhttp+flow 及 kts的全局配置
  • 墨者:SQL过滤字符后手工注入漏洞测试(第3题)
  • npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
  • 什么是ios企业签名?
  • VTK开发笔记(一):VTK介绍,Qt5.9.3+VS2017x64+VTK8.2编译
  • 使用 Django REST Framework 构建强大的 API
  • vue请求golang后端CORS跨域问题深度踩坑
  • 分布式链路追踪详解
  • 图论:Bellman_ford算法