【Linux取经路】文件系统之重定向的实现原理

文章目录
- 一、再来理解重定向
- 1.1 输出重定向效果演示
- 1.2 重定向的原理
- 1.3 dup2
- 1.4 输入重定向效果演示
- 1.5 输入重定向代码实现
- 二、再来理解标准输出和标准错误
- 2.1 同时对标准输出和标准错误进行重定向
- 2.2 将标准输出和标准错误重定向到同一个文件
- 三、再看一切皆文件
- 四、结语
一、再来理解重定向
1.1 输出重定向效果演示

分析:ls 指令是显示当前目录下的文件,本质就是将当前目录下所有的文件名以字符串的形式写入到显示器文件。采用输出重定向 >,将原本应该写入显示器文件的内容写入到了 log.txtx 文件中。
1.2 重定向的原理
在讲解重定向原理前,我们需要明确文件描述符的分配规则,即从0下标开始,寻找最小的没有使用的数组位置,它的下标就是新打开文件的文件描述符。这里没有使用的意思是该下标里面存的是 NULL,即没有指向任何一个文件对象。下面通过一段代码来为大家展示重定向的原理。
// mytest.c
int main()
{close(1);int fd = open(FILE_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0666);if(fd < 0){perror("open");return errno;}const char* str = "Hello Linux!\n";int cnt = 5;while(cnt--){write(1, str, strlen(str));}return 0;
}
代码分析:上面这段代码就完美的展示了重定向的原理。首先调用 close 系统调用将 1 号下标对应的文件关闭,关闭的意思就是将 1 下标里的内容置为 NULL,原本 1 下标里面存储的内容是显示器文件对象的地址,也就是标准输出 stdout,紧接着调用 open 打开了一个文件,根据文件描述符的分配规则,新打开的这个文件的文件描述符就是 1,即文件描述符表(file*的数组)1 号下标里面存储的就是新打开的文件对象的地址。接下来调用 write 接口,向 1 号文件描述符中进行写入,本来 1 号文件描述符对应的是显示器文件,原本向显示器文件中写入的内容,此时就被写入到新打开的文件中,没有向显示器文件中写入,因此屏幕上就不会出现字符串,至此整个重定向的过程就结束啦。

总结:重定向的本质是对数组下标里面的内容进行修改。

1.3 dup2
上面介绍了重定向的原理,下面介绍一下实现重定向的系统调用 dup2。
#include <unistd.h>
int dup2(int oldfd, int newfd);
dup2 的具体实现并不是向上面代码中那样,先将一个文件描述符关闭,然后紧接着再打开一个文件。dup2 的使用方法是,用户在调用 dup2 接口前,正常打开一个文件,不用将显示器文件关闭,此时新打开文件的文件描述符就是 3。接下来调用 dup2 ,将新打开文件的文件描述符作为 oldfd,将显示器文件的文件描述符也就是 1,作为 newfd。我们知道,文件描述符本质上就是数组下标,dup2 函数中执行的工作就是将 oldfd 下标里存储的文件对象地址拷贝到 newfd 下标里面,至此重定向工作就完成了。

小Tips:dup2 的函数形参有一个误导,我们可能会觉得新打开文件的描述符是 newfd,其实不然,这里的 newfd 是将要被覆盖的文件描述符,oldfd 是新打开文件的描述符。
int main()
{// close(1);int fd = open(FILE_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0666);if(fd < 0){perror("open");return errno;}dup2(fd, 1);const char* str = "Hello Linux!\n";int cnt = 5;while(cnt--){write(1, str, strlen(str));}return 0;
}

代码分析:上面就是输出重定向的实现原理,追加重定向只需要把 O_TRUNC 替换成 O_APPEND。
1.4 输入重定向效果演示

分析:cat 指令本来是从键盘文件中获取输入然后写入显示器文件中,采用输入重定向 < 后,是从 log.txt 文件中获取输入然后写入显示器文件中。
1.5 输入重定向代码实现
// 输入重定向
int main()
{int fd = open(FILE_PATH, O_RDONLY);if(fd < 0){perror("open");}dup2(fd, 0);char str[1024];ssize_t ret = read(fd, str, sizeof(str) - 1);if(ret > 0){str[ret] = '\0';printf("echo: %s", str);}return 0;
}

小Tips:进程历史打开的文件与进行的各种重定向关系都和未来进行的程序替换无关,程序替换并不影响文件访问。进程打开文件和何种重定向工作,本质上都是进程管理的模块,而程序替换只会把用户空间的代码和数据完全被新程序替换,不会影响到进程管理。
二、再来理解标准输出和标准错误
int main()
{fprintf(stdout, "Standard output messages\n");fprintf(stdout, "Standard output messages\n");fprintf(stdout, "Standard output messages\n");fprintf(stderr, "Standard error messages\n");fprintf(stderr, "Standard error messages\n");fprintf(stderr, "Standard error messages\n");return 0;
}

代码分析:> 是输出重定向,也就是对标准输出(1号文件描述符)进行重定向。标准错误对应的2号文件描述符并没有进行重定向,因此标准错误消息仍然打印在了屏幕上。
2.1 同时对标准输出和标准错误进行重定向
./mytest 1>output.txt 2>error.txt
小Tips:这段代码就是将1号文件描述符对应的标准输出文件重定向到 output.txt 文件,将2号文件描述符对应的标准错误文件重定向到 error.txt 文件。这样以来屏幕上就不会有任何输出。

2.2 将标准输出和标准错误重定向到同一个文件
./mytest 1>all.txt 2>&1

小Tips:将标准输出和标准错误都重定向到 all.txt 文件中。
三、再看一切皆文件
所有操作计算机的动作,都是通过进程去执行的,所有的访问文件操作,都是通过进程去实现的,目前所有对文件的操作都依赖于进程。

小Tips:所有的外设都被抽象成了文件,每个外设都有自己的读写方法,不同的外设读写方法一定是不同的。但是我们在对文件进行读写操作的时候,始终调用的都是 read 和 write 方法,这是因为操作系统为我们提供了一个方法集类型 file_operations,该结构体里面都是函数指针类型,指向外设的各种方法,这就是多态的雏形。所谓的一切皆文件,就是操作系统帮我们封装了一层文件对象,进程对各种外设的操作,全都变成了对文件的操作。
sszie_t read(int fd)
{task_struct->files->fd_array[fd]->f_op->read();
}
四、结语
今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,春人的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是春人前进的动力!

相关文章:
【Linux取经路】文件系统之重定向的实现原理
文章目录 一、再来理解重定向1.1 输出重定向效果演示1.2 重定向的原理1.3 dup21.4 输入重定向效果演示1.5 输入重定向代码实现 二、再来理解标准输出和标准错误2.1 同时对标准输出和标准错误进行重定向2.2 将标准输出和标准错误重定向到同一个文件 三、再看一切皆文件四、结语 …...
JAVA设计模式结构型模式
一、前言 java设计模式主要分为创建型模式,结构型模式和行为型模式。上一篇主要总结了行为型设计模式,本章总结,结构型模式。像创建型模式就不写了,比较简单。大概知道是工厂模式和建造者模式,原型模式就行࿰…...
第4讲引入JWT前后端交互
引入JWT前后端交互 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519); JWT就是一段字符串,用来进行用户身份认证的凭证,该字符串分成三段【头部、载荷、签证】 后端接口测试&…...
基于Java的车辆租赁管理平台/租车系统
功能介绍 平台采用B/S结构,后端采用主流的Springboot框架进行开发,前端采用主流的Vue.js进行开发。 整个平台包括前台和后台两个部分。 前台功能包括:首页、车辆详情、车辆预订、用户中心模块。后台功能包括:车辆管理、分类管理…...
如何升级至ChatGPT Plus:快速指南,ChatGPT的秘密武器GPT4.0是什么?
提到 ChatGPT。想必大家都有所耳闻。自从 2022 年上线以来,就受到国内外狂热的追捧和青睐,上线2个月,月活突破1个亿!!! 而且还在持续上涨中。因为有很多人都在使用 ChatGPT 。无论是各大头条、抖音等 App、…...
【天衍系列 05】Flink集成KafkaSink组件:实现流式数据的可靠传输 高效协同
文章目录 01 KafkaSink 版本&导言02 KafkaSink 基本概念03 KafkaSink 工作原理1.初始化连接2.定义序列化模式3.创建KafkaSink算子4.创建数据源5.将数据流添加到KafkaSink6.内部工作机制 04 KafkaSink参数配置05 KafkaSink 应用依赖06 KafkaSink 快速入门6.1 包结构6.2 项目…...
深度学习之pytorch实现逻辑斯蒂回归
深度学习之pytorch实现逻辑斯蒂回归 解决的问题数学公式logiatic函数损失值 代码与线性回归代码的区别数据损失值构造回归的函数 结果分析 解决的问题 logistic 适用于分类问题,这里案例( y为0和1 ,0和 1 分别代表一类) 于解决二分类…...
有事休假店铺无人看守怎么办?智能远程视频监控系统保卫店铺安全
在春节期间,很多自营店主也得到了久违的假期,虽然很多店主都是长期在店铺中看守,但遇到春节这样的日子,多数人还是选择回乡休假。面对店主休假或有事不能管理店铺时,传统的监控虽然可以做到单一的监控,却仍…...
酷开科技 | 酷开系统壁纸模式,让过年更有氛围感!
在阵阵爆竹声中,家家户户都沉浸在浓浓的年味中。过年,是团圆,是温暖。团团圆圆的日子里,仪式感不可少,换上一张喜气洋洋的电视壁纸吧,寓意幸福一年又一年。打开酷开系统壁纸模式挑选一张年味十足的壁纸&…...
Docker中部署flink集群的两种方式
文章目录 一、概述二、准备工作三、方式一四、方式二1、准备配置文件2、执行 docker 命令 一、概述 本文将通过 2 种方式在 docker 中部署 flink standalone 集群,集群中共有 4 个节点,分别是 1 个 jobManager 节点和 3 个 taskManager 节点。方式一能快…...
八、计算机视觉-边界填充
文章目录 前言一、原理二、具体的实现 前言 在Python中使用OpenCV进行边界填充(也称为zero padding)是一种常见的图像处理操作,通常用于在图像周围添加额外的像素以便进行卷积或其他操作。下面是使用OpenCV进行边界填充的基本原理和方法 一…...
ffmpeg 硬件加速介绍
基于OS的硬件加速 Windows 参考[2],基于windows的硬件加速都是基于DirectX API,我们可以用ffmpeg -hwaccels查看当前环境支持的硬件加速接口,如下为windows上的执行ffmpeg --hwaccels的结果。 在linux上执行ffmpeg -hwaccels的结果如下: 可以看到windows上支持的硬件加速…...
【QT+QGIS跨平台编译】之三十九:【Exiv2+Qt跨平台编译】(一套代码、一套框架,跨平台编译)
文章目录 一、Exiv2介绍二、文件下载三、文件分析四、pro文件4.1 exiv2-xmp4.2 exiv2lib_int4.3 exiv2lib五、编译实践一、Exiv2介绍 Exiv2是一个开源的C++库,用于读取、编辑和写入图片和视频文件的元数据。它可以处理各种类型的元数据,包括EXIF、IPTC、XMP等。 元数据是与…...
术业有专攻!三防加固平板助力工业起飞
在日常使用中的商业电脑比较追求时效性,以市场定位做标准,内部元件只需满足一般要求就行,使用寿命比较短。而三防平板电脑是主要运用在复杂、恶劣的环境下所以在需求方面较高,需要保证产品在恶劣条件下正常使用,满足行业领域的需求…...
适合tiktok运营的云手机需要满足什么条件?
TikTok作为一款全球热门的社交媒体平台,具有无限的市场潜力。然而,卖家在运营过程中常常会面临到视频0播、账号被降权、限流等问题,甚至可能因为多人同时使用一个IP而导致封号的风险。为了规避这些问题,越来越多的卖家将目光投向了…...
微服务-微服务Nacos配置中心
1.1 配置中心架构 1.2 Config Client源码分析 配置中心核心接口ConfigService public class ConfigServerDemo {public static void main(String[] args) throws NacosException, InterruptedException {String serverAddr "localhost";String dataId "naco…...
配置Python环境及job运行的虚拟环境
1、配置Jenkins的Python环境:Manage Jnekins-Global Tool Configuration-Python 2、安装pyenv插件 此插件会给每个job都创建一个虚拟Python环境 安装后,在job config-build中选择 virtualenv builder build job的时候会自动在/opt/jenkins(node主机的…...
【Java】图解 JVM 垃圾回收(二):垃圾收集器、Full GC
图解 JVM 垃圾回收(二) 1.垃圾收集器1.1 内存分配与回收策略1.2 Serial 收集器1.3 Parallel Scavenge 收集器1.4 ParNew 收集器1.5 CMS 收集器1.6 G1 收集器 2.Full GC 的触发条件 1.垃圾收集器 Java 虚拟机提供了多种垃圾回收器,每种回收器…...
Opencv绘图之rectangle、circle、line、ellipse、Rect、RotatedRect、Point
OpenCV中提供了多种函数来在图像上绘制各种基本形状,如矩形、圆形、线条、椭圆等。同时,Rect和RotatedRect是用来表示矩形区域的类,它们在图像处理中非常有用,尤其是在需要定义和操作图像区域时。Point类用于表示二维空间中的一个…...
HTML 字符实体参考清单
前言 一些字符在 HTML 中是预留的,拥有特殊的含义,比如小于号‘<’用于定义 HTML 标签的开始。如果我们希望浏览器正确地显示这些字符,我们必须在 HTML 源码中插入字符实体。 字符实体有三部分:一个和号‘&’和一个实体名…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
