【Linux系统编程十五】:(基础IO2)--重定向实现原理 “Linux下一切皆文件“

news2024/11/24 9:55:11

【Linux系统编程十五】:重定向原理 与 "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/1190066.html

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

相关文章

HTTP协议 和 HTTPS协议

一、HTTP协议: HTTP协议是超文本传输协议的缩写,英文是Hyper Text Transfer Protocol。它是从WEB服务器传输超文本标记语言(HTML)到本地浏览器的传送协议。 设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。HTPP有多个版本,目前…

Read Completion Boundary (RCB)切分规则

Read Completion Boundary(RCB) 切分规则 Read Completion Boundary(RCB) 简介 当Read Completion 包含multi-completions时,RCB 规定了多个Completions地址的align规则。Spec中规定RCB可以是64 Byte或者128 Byte,该值可以在link_control register中得…

什么是观察者模式?用 Python 如何实现 Observer(观察者或发布订阅)对象行为型模式?

什么是观察者模式? 观察者模式(Observer pattern)是一种行为型设计模式,它允许对象之间建立一种一对多的依赖关系,当一个对象的状态发生变化时,其相关依赖对象都会得到通知并自动更新。 在观察者模式中&am…

Leo赠书活动-06期 【强化学习:原理与Python实战】文末送书

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 赠书活动专栏 ✨特色专栏:…

CVE-2023-0179-Nftables整型溢出

前言 Netfilter是一个用于Linux操作系统的网络数据包过滤框架,它提供了一种灵活的方式来管理网络数据包的流动。Netfilter允许系统管理员和开发人员控制数据包在Linux内核中的处理方式,以实现网络安全、网络地址转换(Network Address Transl…

MySQL 数据库表格创建、数据插入及获取插入的 ID:Python 教程

创建表格 要在MySQL中创建表格,请使用"CREATE TABLE"语句。 确保在创建连接时定义了数据库的名称。 示例创建一个名为 “customers” 的表格: import mysql.connectormydb mysql.connector.connect(host"localhost",user"…

图文解析 Nacos 配置中心的实现

目录 一、什么是 Nacos 二、配置中心的架构 三、Nacos 使用示例 (一)官方代码示例 (二)Properties 解读 (三)配置项的层级设计 (四)获取配置 (五)注册…

nfs配置

1.NFS介绍 NFS就是Network File System的缩写,它最大的功能就是可以通过网络,让不同的机器、不同的操 作系统可以共享彼此的文件。 NFS服务器可以让PC将网络中的NFS服务器共享的目录挂载到本地端的文 件系统中,而在本地端的系统中来看&#…

【gltf-pipeline】安装gltf-pipeline 进行文件格式转换

问题 想使用gltf-pipeline进行gltf和glb格式转换。简单记录一下安装过程。 解决 1、安装Node.js Node.js下载路径:https://nodejs.org/en 建议默认设置安装。 添加系统环境变量: 测试安装是否成功: 在cmd.exe中运行: no…

基于SSM的建筑装修图纸管理平台

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

基于ssm的校园办公室报修管理系统

基于ssm的校园办公室报修管理系统 摘要 基于SSM的校园办公室报修管理系统是一个现代化的、高效的报修平台,它能够帮助校园内的教职工和学生更方便、更快捷地提交和处理报修请求。该系统基于Spring、SpringMVC和MyBatis(简称SSM)开发&#xff…

【MySQL】一文学会所有MySQL基础知识以及基本面试题

文章目录 前言 目录 文章目录 前言 一、主流数据库以及如何登陆数据库 二、常用命令使用 三、SQL分类 3.1 存储引擎 四、创建数据库如何设置编码等问题 4.1操纵数据库 4.2操纵表 五、数据类型 六、表的约束 七、基本查询 八、函数 九、复合查询 十、表的内连和外连 十一、索引…

第十八章Swing程序设计总结

例题18.1:第一个窗体程序 例题18.2:在窗体中弹出对话框 例题18.3:弹出会话框,问用户准备好了吗? 例题18.4:弹出会话框,询问用户是否离开 例题18.5:弹出会话框,让用户输入…

特殊矩阵的压缩存储(对称矩阵,三角矩阵,三对角矩阵,稀疏矩阵)

目录 1.数组的存储结构1.—维数组2.二维数组1.行优先存储2.列优先存储 2.特殊矩阵1.对称矩阵1.行优先存储 2.三角矩阵1.上三角矩阵2.下三角矩阵 3.三对角矩阵(带状矩阵)4.稀疏矩阵 1.数组的存储结构 1.—维数组 各数组元素大小相同,且物理上…

vue-router路由守卫进阶

vue-router路由守卫进阶 路由守卫,可以想象为古代御前侍卫,路由守卫,则是对路由进行权限控制 分类:全局守卫、独享守卫、组件内守卫 全局前置-路由守卫 作用:主要用来鉴权 用户点击导航区,随后引起路径的…

Android平台上执行C/C++可执行程序,linux系统编程开发,NDK开发前奏。

Android平台上执行C/C可执行程序,linux系统编程开发,NDK开发前奏准备。 1.下载NDK,搭建NDK开发环境 下载地址 https://developer.android.com/ndk/downloads 下载过程中点击下面箭头的地方,点击鼠标右键,复制好下载…

自动化实战 - 测试个人博客系统

前言 本篇使用Selenium3Junit5对个人博客进行自动化测试,如有错误,请在评论区指正,让我们一起交流,共同进步! 文章目录 前言一.web自动化测试用例二.测试准备1.注册界面自动化测试测试过程中遇到的Bug: 2.登录界面自动…

坐标系转换(仅作记载)

一.极坐标转换为普通坐标系 参考:极坐标方程与直角坐标方程的互化 - 知乎 (zhihu.com) 公式:(无需考虑象限引起的正负问题) 普通坐标系转换为极坐标系 参考: 极坐标怎么与直角坐标系相互转化? - 知乎 (zh…

若依 验证码出不来 Fontconfig head is null, check your fonts or fonts configuration

是因为使用的OenJDK不支持awt包下的字体 解决方法: 安装FontConfig组件即可 yum install -y fontconfig

找不到模块“./App.vue”或其相应的类型声明。ts(2307)

先看报错信息: 这是我们初始创建是就自带的,怎么会错误呢,实际上是因为未定义 .vue文件的类型,导致 ts 无法解析其类型,在env.d.ts中定义后即可解决。 对于我们初学者来说,刚刚按照视频来创建的项目怎么啥…