【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 下标里面,至此重定向工作就完成了。
在这里插入图片描述
小Tipsdup2 的函数形参有一个误导,我们可能会觉得新打开文件的描述符是 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:所有的外设都被抽象成了文件,每个外设都有自己的读写方法,不同的外设读写方法一定是不同的。但是我们在对文件进行读写操作的时候,始终调用的都是 readwrite 方法,这是因为操作系统为我们提供了一个方法集类型 file_operations,该结构体里面都是函数指针类型,指向外设的各种方法,这就是多态的雏形。所谓的一切皆文件,就是操作系统帮我们封装了一层文件对象,进程对各种外设的操作,全都变成了对文件的操作。

sszie_t read(int fd)
{
	task_struct->files->fd_array[fd]->f_op->read();
}

四、结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,春人的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是春人前进的动力!

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Camtasia 2023 v23.4.2.51146 Win功能强大的屏幕录制和视频编辑软件

Camtasia 2023.3.4.2是一款适用于各类用户的屏幕录制和视频编辑软件&#xff0c;特别适合需要制作教育、培训和营销视频的专业人士。它结合了易用性和多样的功能&#xff0c;使视频制作变得更加高效和专业。 软件安装 适用于 Win10.win11系统 1.直接安装软件&#xff0c;安装…

redis scan命令导致cpu飙升

一.背景 今天下午Redis的cpu占用突然异常升高&#xff0c;一度占用达到了90%&#xff0c;触发了钉钉告警&#xff0c;之后又回到正常水平&#xff0c;跟DBA沟通&#xff0c;他说主要是下面这个语句的问题 SCAN 0 MATCH fastUser:6136* COUNT 10000这个语句的执行时长很短&…

nginx 日志改为json格式

nginx 日志改为json格式 场景描述效果变更旧样式新样式 场景描述 正常使用nginx时&#xff0c;使用默认的日志输出格式&#xff0c;对于后续日志接入其他第三方日志收集、清洗环节&#xff0c;因分隔符问题可能不是很友好。 xxxx - - [19/Feb/2024:11:16:48 0800] "GET …

并发编程线程安全之同步锁Synchronized

一、原子性定义 原子性的本质是互斥访问&#xff0c;同一时刻只有一个线程对它进行访问操作 二、原子性问题的简述 public class AutomicDemo {int count 0;public static void main(String[] args) throws InterruptedException {AutomicDemo automicDemo new AutomicDem…

Idea启动Gradle报错: Please, re-import the Gradle project and try again

Idea启动Gradle报错&#xff1a;Warning:Unable to make the module: reading, related gradle configuration was not found. Please, re-import the Gradle project and try again. 解决办法&#xff1a; 开启步骤&#xff1a;View -> Tool Windows -> Gradle 点击refe…

解锁创意灵感,探索FlutterExampleApps项目的奥秘

解锁创意灵感&#xff0c;探索FlutterExampleApps项目的奥秘 项目简介 FlutterExampleApps项目是一个包含各种示例应用链接的仓库&#xff0c;旨在演示Flutter应用开发中的各种功能、特性和集成。 项目包含了以下几个部分&#xff0c;每个部分都涵盖了不同的内容和主题&…

哈希(哈希散列数据结构)---底层原理

Day02: 1.哈希散列数据结构&#xff1a;底层实现就是&#xff1a;数组链表&#xff08;红黑树&#xff09; map的put方法和get方法。 2.数组方法和链表存取数据的区别 数组方法&#xff1a;法随机访问快 链表&#xff1a;增删改效率快。 3.哈希结合了链表和数组的特性。 …

在四维轻云中,如何实现地理空间数据云管理?

四维轻云是一款轻量化的地理空间数据网页管理平台&#xff0c;支持倾斜模型(.osgb)、激光点云(.las)、正射影像(dom)和数字高程模型(dem)等多种地理空间数据的在线管理、编辑及分享&#xff0c;其他类型地理空间数据也将陆续上线。 目前&#xff0c;平台具有项目管理、数据上传…

营销短信群发的注意事项?短信营销的优点?

营销短信的关键是什么&#xff1f;群发国际营销短信的好处&#xff1f; 营销短信作为一种高效、直接的推广方式&#xff0c;越来越受到企业的青睐。然而&#xff0c;要想让营销短信发挥最大的效果&#xff0c;就需要注意一些关键事项。接下来&#xff0c;蜂邮EDM将深入探讨营销…

【Java多线程】线程安全问题与解决方案

目录 1、线程安全问题 1.2、线程安全原因 2、线程加锁 2.1、synchronized 关键字 2.2、完善代码 2.3、对同一个线程的加锁操作 3、内容补充 3.1、内存可见性问题 3.2、指令重排序问题 3.3、解决方法 3.4、总结 volatile 关键字 1、线程安全问题 某个代码&#xff…

2023年全球前端大技术大会(GMTC北京站2023):核心内容与学习收获(附大会核心PPT下载)

此次峰会是一次内容丰富、有深度和广度的技术盛会。参会者不仅可以了解前端技术的最新发展和未来趋势&#xff0c;还可以与业界专家交流心得&#xff0c;提升自己的技能和能力。同时&#xff0c;此次大会也促进了全球前端社区的交流和合作&#xff0c;推动了前端技术的创新和发…

DP读书:《openEuler操作系统》(十)套接字 Socket 数据传输的基本模型

10min速通Socket 套接字简介数据传输基本模型1.TCP/IP模型2.UDP模型 套接字类型套接字&#xff08;Socket&#xff09;编程Socket 的连接1.连接概述(1)基本概念(2)连接状态(3)连接队列 2.建立连接3.关闭连接 socket 编程接口介绍数据的传输1. 阻塞与非阻塞2. I/O复用 数据的传输…

【数据分享】2014-2024年全国监测站点的逐时空气质量数据(15个指标\Excel\Shp格式)

空气质量的好坏反映了空气的污染程度&#xff0c;在各项涉及城市环境的研究中&#xff0c;空气质量都是一个十分重要的指标。空气质量是依据空气中污染物浓度的高低来判断的。 我们发现学者王晓磊在自己的主页里面分享了2014年5月以来的全国范围的到站点的逐时的空气质量数据&…

绝地求生:四大成长武器 满级效果好到爆 钱包真保不住了

刚才看了上手时机视频 说真的这次的四大成长皮肤 只能说是好看到爆啊 小伙伴们&#xff0c;这次过年的路费 可能就要被冲没有了 先来看看悟空的武器特写吧&#xff01; 悟空的皮肤是M24成长皮肤 也是不错 炫酷的很哦 仔细看枪托的细节 是由紧箍咒的形状哦&#xff0c;这下…

Flink Catalog 解读与同步 Hudi 表元数据的最佳实践

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

【C语言的小角落】逻辑与逻辑或混合计算

关注小庄 顿顿解馋(≧◡≦) 引言&#xff1a;本篇博客小庄带领小伙伴们解决一个比较角落有时头疼的问题—关于逻辑与和逻辑或结合运算的问题&#xff0c;请放心食用~ 我们先放代码说话 int main() {int x 1;int y 3;int z 4;if(x1 || y && z){;} printf("y …

自动驾驶中之定位总结

1 前言2 典型的单个定位方式2.1 基于通信的定位方法2.1.1 GNSS 全球卫星导航系统2.1.1.1 gnss的优点与缺点2.1.1.2 gnss定位技术2.1.1.2.1 RTK定位技术2.1.1.2.2 PPP定位技术 2.1.1.2 gnss定位技术总结 2.1.2 车联网定位 2.1 基于航位推算的定位方法2.1.1 惯性测试单元定位IMU2…

unity 使用VS Code 开发,VS Code配置注意事项

vscode 对应的插件&#xff08;unity开发&#xff09; 插件&#xff1a;.Net Install Tool,c#,c# Dev Kit,IntelliCode For C# Dev Kit,Unity,Unity Code Snippets 本人现在是用了这些插件 unity需要安装Visual Studio Editor 1、.Net Install Tool 设置 需要在设置里面配置…

美容小程序:让预约更简单,服务更贴心

在当今繁忙的生活节奏中&#xff0c;美容预约常常令人感到繁琐和疲惫。为了解决这个问题&#xff0c;许多美容院和SPA中心已经开始采用美容小程序来简化预约流程&#xff0c;并提供更加贴心的服务。在这篇文章中&#xff0c;我们将引导您了解如何制作一个美容小程序&#xff0c…

网络安全--网鼎杯2018漏洞复现(二次注入)

一、环境&#xff1a;在线测试平台 BUUCTF在线评测 (buuoj.cn) 二、进入界面先尝试万能账号 1or11# 换格式 hais1bux1 11or11# 三、万能的不行那我们就得想注册了&#xff0c;去register.php去看看 注册个账号 发现用户名回显&#xff0c;猜测考点为用户名处二次注入&…