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

【Linux】fd_重定向本质

hello~ 很高兴见到大家! 这次带来的是Linux系统中关于基础 IO这部分的一些知识点,如果对你有所帮助的话,可否留下你宝贵的三连呢?
个 人 主 页: 默|笙


文章目录

  • 一、理解重定向本质
      • 1.1 linux分配文件描述符遵循最小可用原则- - -分配规则
      • 1.2 IO函数只认文件描述符,不认特定的文件
      • 1.3 dup2系统调用
  • 二、初步认识一切皆文件

一、理解重定向本质

1.1 linux分配文件描述符遵循最小可用原则- - -分配规则

  1. 在之前的学习中,我们知道每一个进程运行之后,都会默认打开三个文件,分别是标准输入流,标准输出流和标准错误流,它们分别对应文件描述符0、1、2。而进程新打开的文件则会分配从3开始依次往后的文件描述符。
10intfda=open("log.txt1",O_WRONLY|O_CREAT|O_TRUNC,0666);11intfdb=open("log.txt2",O_WRONLY|O_CREAT|O_TRUNC,0666);12intfdc=open("log.txt3",O_WRONLY|O_CREAT|O_TRUNC,0666);13printf("fda: %d\n",fda);14printf("fdb: %d\n",fdb);15printf("fdc: %d\n",fdc);

  1. 如果我们人为将这三个默认打开的文件关闭再打开一个新的文件log.txt会怎么样—>关闭标准输入流文件,那么文件描述符为0的位置就会空出来,这个时候3就不是最小且可以分配的文件描述符了,也就是说,log.txt的文件描述符会是0,而不是3。可以通过下面的代码进行验证:
9close(0);10intfp=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);11printf("fp: %d\n",fp);

1.2 IO函数只认文件描述符,不认特定的文件

  1. C语言里面stdin、stdout和stderr都是对文件描述符fd的抽象封装,这也就意味着这三个流它们是不认识这些文件描述符所对应的文件的。一般stdin对应键盘文件,stdout和stderr对应显示器文件。如果将这些fd对应的文件替换掉,是不是就能够实现从其他文件进行输入输出了呢?是的。我们可以用下面这段代码进行验证:
10close(1);11intfp=open("log.txt",O_WRONLY|O_CREAT|O_TRUNC);12printf("fp: %d\n",fp);

  1. 这里可以看到,如果我们把标准输出流关闭之后,printf要打印的内容在test执行之后没有显示在显示器上,而是打印到了log.txt文件里面,这是因为printf这个io函数它只认文件描述符1,它会把内容打印到文件描述符1对应的文件里面。在把标准输入流关闭打开一个新文件log.txt之后,文件描述符1就归log.txt这个文件了,printf要打印的内容自然就会打印到文件log.txt里面,而非显示器文件了。这就是为什么我们执行test看不到打印的内容而查看log.txt文件能够看到打印内容的原因。

  1. 我们通过关闭原来的输入输出流然后打开新的文件来代替要进行IO操作的显示器,键盘文件来实现对不同的文件输入输出。不过,现在一般是先打开新文件,然后将这个新文件覆盖掉原来的输入输出流对应文件。替换原输入输出流(键盘 / 显示器)对应的文件描述符(0/1/2)来达到对其他文件的IO操作,这就是重定向的本质
  2. 这里替换标准输入流对应文件也是一样,它不会再从键盘读取数据而是从文件描述符0对应的文件里面读取数据。
10close(0);11intfp=open("log.txt",O_RDONLY);12printf("fp: %d\n",fp);13chars[10];14scanf("%s",s);15printf("%s\n",s);

  1. 事先我往已经存在的文件 log.txt 输入了一串字符helloworld,然后将文件描述符0对应的文件改为log.txt,之后用scanf读取log.txt文件内容再打印到显示器上,如果我们不改变文件描述符0对应文件,那么它应该从键盘读取数据,改变之后自然就从log.txt文件里面读取数据了。

1.3 dup2系统调用

  1. dup2这个接口就是专门用来改变文件描述符的,它的原理是进行覆盖,即用oldfd对应的文件覆盖newfd原本的绑定关系。比如上面我们用 log.txt代替了文件描述符0/1对应的文件,那么log.txt对应的文件描述符就是oldfd,而文件描述符0/1就是newfd。
  2. 有了这个函数,就不用通过关闭再打开文件进行替换操作,而是直接进行覆盖。
    10.进行程序替换是不会影响到进程已经打开的文件的。

二、初步认识一切皆文件

  1. 我们知道Linux系统里面一切皆文件,那么硬件在Linux系统里面也会是一个文件。OS要对这些硬件文件进行管理,一定也是先描述再组织,也就是把硬件的属性等其他内容打包成一个结构体struct_file。
  2. 对每个硬件进行操作,其实无非两种,输入和输出操作即IO操作。但是每一个硬件设备它们的访问方式都各不相同,比如键盘是输入,它的输出操作没有意义,显示器则与之相反。每一个硬件设备都有自己的输入和输出操作(驱动方法),要让OS对这些硬件以及其他文件进行统一操作,就需要对struct_file进行改造,加入operations模块绑定对应专属的IO操作,这样就实现了对不同的硬件进行统一操作。它类似于c++里面的多态。

今天的分享就到此结束啦,如果对读者朋友们有所帮助的话,可否留下宝贵的三连呢~~
让我们共同努力, 一起走下去!

http://www.jsqmd.com/news/371663/

相关文章:

  • 4:Web基础漏洞利用深度剖析
  • 在仿真优化项目里的数据库选型,OpenTeleDB的Xstore存储引擎应用
  • 基于模块化设计的可定制化推理系统框架
  • OpenLoong项目是什么?
  • 能源之星X(笔记本省电)
  • 前端开发:点击事件使用 @click.prevent 的场景总结
  • FreeRTOS:任务通知(Task Notifications)与事件组(Event Groups)
  • 嵌入式常见屏幕
  • 【计算机基础】-13-什么是内存屏障
  • 系统机械师System Mechanic Pro
  • 让AI成为您的获客引擎:doubaoAD以GEO策略驱动高质量线索增长 - 品牌2025
  • 2026年2月11日
  • FreeRtos中钩子函数的不同应用
  • 抢占AI时代新流量入口:doubaoAD引领豆包GEO智能营销新范式 - 品牌2025
  • FreeRTOS: 软件定时器(Software Timers)与时间管理
  • Java毕设项目:基于springboot的某校大学学生就业信息平台(源码+文档,讲解、调试运行,定制等)
  • Thorium(电子书阅读)
  • 2026市面上好用的循环水阻垢剂厂家推荐 - 品牌排行榜
  • 从理论到实践:数据立方体在大数据项目中的落地
  • 豆包用户量登顶,AI营销窗口期已至——品牌必须回答的三个关键问题 - 品牌2025
  • 【计算机毕业设计案例】基于Web的农产品直卖平台的设计与实现基于springboot的优质农产品销售平台设计和实现(程序+文档+讲解+定制)
  • AI魔术师
  • Magnific AI:拒绝“马赛克”?AI 幻觉重绘流,拯救 1024px 废片
  • 2026年市面上水质稳定剂厂家推荐及行业解析 - 品牌排行榜
  • 2月12日直播 | CANN算子一站式开发平台全面公测
  • 2026年市面上缓蚀阻垢剂厂家推荐 - 品牌排行榜
  • 2026年市面上PH调节剂厂家推荐及行业应用解析 - 品牌排行榜
  • 把握AI时代新机遇:通过doubaoAD.com提升品牌在豆包中的影响力 - 品牌2025
  • AI原生应用架构演进:从CRUD到事件驱动
  • 【毕业设计】基于springboot的优质农产品销售平台设计和实现(源码+文档+远程调试,全bao定制等)