【基础IO⑨】:重定向实现原理 “Linux下一切皆文件“

news2024/11/26 21:45:57

【基础IO⑨】:重定向原理 与 "Linux下一切皆文件"

  • 一.重定向
    • 1.实现原理
    • 2.输出重定向
    • 3.输入重定向
    • 4.补充:简易shell中实现重定向
  • 二."Linux下一切皆文件"
    • 1.虚拟文件系统(VFS)

一.重定向

在这里插入图片描述
我们首先关闭2号文件描述符,然后再打开一个文件log.txt。并且打印这个文件的文件描述符。最后我们将发现这个文件的文件描述符是2。
这是为什么呢?很简单,因为文件描述符的填充是从上往下,从0开始填没有被占用的位置,因为2号位置被关闭了,所以普通文件log.txt就被放进2号里面了。

我们知道三个标准输入输出流stdin,stdout,stderr分别代表这键盘文件,显示器文件,显示器文件。它们默认是被打开的,也就分别占用着0,1,2文件描述符。
当我们再打开一个文件时,就默认占用的是3号文件描述符。
不过如果我们利用上面的原理,先关闭一个文件,那么这个文件描述符位置上就空缺了,然后再打开一个文件,那么这个文件就会被填到原来的文件的位置里去。
在这里插入图片描述
在这里插入图片描述
比如先将1号描述符位置上的文件关闭,即将显示器文件关闭。然后再打开普通文件,这时,1号描述符位置上的文件地址就变成普通文件了。
然后我们当向1号描述符输出时,就会重定向输出到普通文件里。

1.实现原理

实现重定向的原理其实就是覆盖文件描述符里文件地址。因为文件描述符是不变的,只能改变文件描述符里面的文件地址。原来1号描述符指向的显示器文件,如果1号描述符里的显示器文件地址被覆盖成普通文件地址,那么1号描述符就指向普通文件。当我们往1号描述符输出时,就会输出到文件里。

所以重定向的本质就是:文件描述符数组里的内容拷贝

不过这样写有点low,先关闭一个文件,再打开一个文件。因为重定向的本质就是文件描述符数组里面文件地址的拷贝,所以系统提供一些系统调用接口,可以帮助我们直接拷贝:
在这里插入图片描述
在这里插入图片描述
dup2(int oldfd,int newfd)接口的功能就是让oldfd作为拷贝对象拷贝给newfd。其实就是让oldfd文件描述符里的文件对象拷贝给newfd文件描述符里的文件对象,最后newfd文件描述符就指向了oldfd文件描述符指向的文件了。

在这里插入图片描述

2.输出重定向

在这里插入图片描述
当我们往1号描述符里输出时,就会输出到普通文件里,而不是输出到显示器上。这就是输出重定向。

3.输入重定向

在这里插入图片描述
当我们从0号文件符里获取输入时,本来是从键盘上获取输入,但是却从文件里获取到了输入内容,这就是输入重定向。

注意:
1.printf里封装的是1号描述符,它只知道往1号描述符里的文件对象输出,但它并不知道1号描述符里的文件对象是谁,也不关心是谁。
2.在这里插入图片描述

4.补充:简易shell中实现重定向

在这里插入图片描述
在重定向之前需要先打开文件,这样才可以获取对应的文件描述符,才可以利用文件描述符重定向。

并且在进行重定向过程中,进程如果发生程序替换是不会受影响的!
在这里插入图片描述

二.“Linux下一切皆文件”

Linux下一切皆文件,这句话你是不是在学习Linux中不断的听过,但是你理解它吗?为什么在Linux下一切皆文件呢?

首先我们先理解:

1.所有的操作计算机的动作都是以进程的形式进行的。
2.所有访问文件操作都是直接通过进程方式访问的。
3.每一种外设硬件都有自己的方式去读写。虽然方法都不一样,但方法种类却类似,都是读和写。

Linux在上层不关心底层访问的是什么设备,不管是键盘,还是显示器,还是网卡等都看成文件。以文件的方式读写访问设备。
Linux中是如何做到这样的呢?

1.虚拟文件系统(VFS)

我们知道当进程访问文件时,操作系统会给这个文件创建一个文件对象。这个文件对象的地址会被放进文件描述表里。
操作系统创建的文件对象会以链表的形式链接起来,而这软件层
被称为虚拟文件系统VFS。

因为硬件都有自己的方法读写,虽然方法不同,但却有共性。那么我们就可以将这个共性组成一个结构体,里面存储着函数指针,分别是读函数指针和写函数指针。当调用具体函数指针时,就会去调用对应的方法。
而这个结构体称为 操作方法指针集。里面的指针分别指向对应的外设自己的读取方法。

所以每打开一个文件,操作系统还会创建一个对应的读取方法集对象。这个结构体对象里存着许多函数指针,分别对应着底层外设的读写方法。
当你要打开键盘时,操作系统就将键盘的读写方法初始化这个方法集对象,这样调用这个方法集对象里的具体函数指针就是键盘的访问操作。
当打开的是显示器,操作系统就会将显示器的读写方法初始化给方法集对象,调用方法集对象里的函数指针就能正确的使用显示的读取方法。

而在文件对象里存储着方法集对象的指针,可以通过该指针找到方法集对象,继而可以调用对应的外设访问方法。

在这里插入图片描述

所以Linux是如何不需要管底层设备是什么,都可以按照文件的方式进行访问呢?
1 . 因为在打开的每个文件对象里都有对应的指针指向方法集结构,里面的函数指针可以找到对应访问外设的正确方法。
2 .所以在进程看来,它可能不知道调用什么方法访问外设,但只要创建了文件对象,那么这个文件对象里就有指针可以找到对应的方法集。所以进程想要访问谁,只需要打开对应的文件。

所以哪和设备想被打开,想被访问,也就是要将自己的设备读取方法给文件对象。文件对象里会存储一个指针,指向方法集合。

不管是什么设备,只要操作系统创建出来对应的struct file对象。就可以正确访问该设备。
因为操作系统会将该设备的读取方法初始化给方法集对象。而文件对象里有有一个指针可以指向方法集对象。
在这里插入图片描述
总结:
操作系统启动时会创建一个软件层VFS,当外设要打开时,就会创建对应的文件对象,就会创建对应的函数指针对象,将函数指针初始化为底层设备具体的方法操作。
每种设备都有对应的struct file对象,都有函数指针对象。函数指针指向不同的方法。所以进程不管是什么设备,直接通过文件对象里函数指针对象里函数指针,调用读_函数指针获取读操作,写函数指针获取写操作。所以在上层直接调用read和write就可以访问底层的读写方法,里面肯定是这样封装的:在这里插入图片描述
所以软件层VFS包裹着底层硬件的差异,给上层提供统一的文件操作接口,用统一的文件接口对不同的设备进行访问。这就是:一切皆文件!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1177582.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apple :苹果将在明年年底推出自己的 AI,预计将随 iOS 18 一起推出

本心、输入输出、结果 文章目录 Apple :苹果将在明年年底推出自己的 AI,预计将随 iOS 18 一起推出前言三星声称库克相关图片弘扬爱国精神 Apple :苹果将在明年年底推出自己的 AI,预计将随 iOS 18 一起推出 编辑:简简单…

MySQL——Centos7下环境安装

目录 0.说明 1. 检查环境(systemctl start/stop/restart) 2. 检查系统安装包(rpm -qa) 3. 卸载这些默认安装包(yum remove、xargs) 4. 获取mysql官方yum源 5. 安装mysql yum源,对比前后yu…

【网络】五中IO模型介绍 + 多路转接中select和poll服务器的简单编写

高级IO 前言正式开始前面的IO函数简单过一遍什么叫做低效的IO钓鱼的例子同步IO和异步IO五种IO模型阻塞IO非阻塞IO信号驱动多路转接异步IO 小结 代码演示非阻塞IO多路转接select介绍简易select服务器timeout 为 nullptrtimeout 为 {0, 0}timeout 为 {5, 0}调用accept select编写…

已经不做程序媛4年半了,后悔么?不好说...但再次看到之前写的博客,真的感慨万分。

四年半前,我还在大四实习,做了一年Java开发。四年半后,我是地理信息行业的一名销售经理。 今天,突然点开了CSDN,看到自己的博客有很多人看过,霎时间感慨万千…因为上一次这么认真的对待自己,竟…

网络运维Day06

文章目录 磁盘空间管理一块硬盘的“艺术”之旅识别磁盘分区规划分区模式MBR(主启动记录模式)GPT分区 使用GPT分区方案分区 格式化与挂载使用格式化挂载使用 实现开机自动挂载实验 光盘挂载交换空间 总结 磁盘空间管理 磁盘空间管理 扇区默认512字节 一块硬盘的“艺术”之旅 …

【Spring】spring中存储Bean(对象)的相关注解及相关用法

五大注解:Controller,Service,Repository,Component,Configuration 1、controller 控制器(注入服务) 控制层,接收请求,对请求进⾏处理,并进⾏响应。用于标注控制层,相当于struts中的…

【mmcv报错】ModuleNotFoundError: No module named ‘mmcv.runner

跑一个代码需要用到mmcv和mmseg 其中有两行代码: from mmcv.runner import load_checkpoint from mmseg.utils import get_root_logger我先是按照官方推荐的安装方法去安装了mmcv和mmseg pip install -U openmim mim install mmcv它会自动帮你安装mmengine 我的cu…

关于Vue使用props传值遇到的一些问题

一、The data property “tableData” is already declared as a prop. Use prop default value instead. 翻译过来:数据属性“tableData”已声明为prop。请改prop默认值。 将父组件的prop传过去变量改一下 二、prop传值,子组件比父组件先渲染&#…

内存取证 worldskills3.vmem与gs02.jpg题目WP

worldskills3.vmem 题目信息 获取admin用户密码是多少? 获取ip和主机名是什么? 获取桌面上的flag.txt文件的内容是什么? 服务器存在一个挖矿病毒,矿池地址是? 恶意代码在系统中注册了服务,服务名是什么&a…

pytest 的使用===谨记

发现用例的规则 a) 文件test_.py开头和_test.py结尾 b) Test开头的类中test开头的方法(测试类不能带有__init__方法) c) 模块中test开头的函数(可以不在class中) 注意点: pytest是以方法为单位发现用例的,你…

单通道低压 H 桥电机驱动芯片AT9110H 兼容L9110 马达驱动芯片

H桥直流电机驱动电路是一种用于控制直流电机运转的电路,其主要特点是可以实现正反转控制,控制电机转速和方向,同时也具有过流保护功能。 H桥电路由四个功率晶体管和一些辅助电路组成,其中两个晶体管用于控制电机正转,…

SciCoMap颜色包_共180种--全平台可用

SciCoMap颜色包_共180种–全平台可用 往期推荐: 海洋专用cmocean颜色包_共22种–全平台可用 Python语言_matplotlib包_共80种–全平台可用 Python语言_single_color_共140种–全平台可用 R语言_RColorBrewer包–全平台可用 R语言gplots包的颜色索引表–全平台可用 …

Linux-Shell命令行解释器的模拟实现

引言:本篇文章主要是简单实现一个shell命令行解释器,可以支持基础常见的linux的命令,支持内建命名echo、cd,同时支持重定向的操作! 一、代码剖析 1. 头文件引入: 因代码是在linux下实现,引入的…

性能测试知多少---了解前端性能

我的上一篇博文中讲到了响应时间,我们在做性能测试时,能过工具可以屏蔽客户端呈现时间,通过局域网的高宽带可以忽略数据传输速度的障碍。这并不是说他们不会对系统造成性能影响。相反,从用户的感受来看,虽然传输速度受…

阿里巴巴1688商品详情 API 接口示例

1688.item_get 公共参数 请求地址: https://o0b.cn/anzexi 名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)secretString是调用密钥api_nameString是API接口名称(包括在请求地址中)[item_search,item_get,item_…

软件外包开发质量控制方法

在软件外包开发项目中,质量控制是确保交付的软件符合预期质量标准的关键步骤。以下是一些常用的软件外包开发质量控制方法,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 需求明确&#x…

wpf添加Halcon的窗口控件报错:下列控件已成功添加到工具箱中,但未在活动设计器中启用

报错截图如下: 注意一下新建工程的时候选择wpf应用而不是wpf应用程序。 添加成功的控件:

博弈论——霍特林博弈(Hotelling Game)

0 引言 前一篇文章在特殊的伯特兰德博弈模型的基础上,解释了伯特兰德悖论,我们先简单回顾一下: 三个假设: (1)各寡头厂商通过选择价格进行竞争; (2)各寡头厂商生产的产品…

Devchat-AI 编程助手:Devchat-AI 尝鲜测评+场景实践

本心、输入输出、结果 文章目录 Devchat-AI 编程助手:Devchat-AI 尝鲜测评场景实践前言DevChat 简介DevChat 是什么DevChat AI 编程助手有哪些优势 DevChat 的申请和使用运行环境要求DevChat 的申请DevChat 激活DevChat 定价DevChat 的安装DevChat 的简单使用 相关图…