Linux文件:重定向底层实现原理(输入重定向、输出重定向、追加重定向)
Linux文件:重定向底层实现原理(输入重定向、输出重定向、追加重定向)
- 前言
- 一、文件描述符fd的分配规则
- 二、输出重定向(>)
- 三、输出重定向底层实现原理
- 四、追加重定向(>>)
- 五、输入重定向(<)
- 六、系统调用dup2
- 七、标准错误stderr存在意义
前言
在Linux中,操作系统会为每一个文件创建对应的描述结构体对象struct file。该结构体中一定存在3个部分:打开文件的所有属性、文件的操作集、文件缓冲区(内存)。其中由于冯诺依曼体系决定了,无论对文件进行读操作还是写操作,都需要先将数据加载到文件缓存区!
我们在应用层进行对数据读写的操作本质上是用户缓冲区和内核数据缓冲区之间的相互拷贝!!!
一、文件描述符fd的分配规则
- 默认情况下,进程会默认打开3个文件:标准输入、标准输出、标准错误。
- 文件描述符的分配规制是:从上往下遍历查找最小的、未被使用的分别个新的文件!
二、输出重定向(>)
下面我们将标准输出文件关闭,然后创建新的文件;并向新的文件中输出一些信息。
int main()
{close(1); //将标准输出文件显示器关闭int fd = open("log.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);//新创建文件,fd分配为1 if(fd < 0) { perror("open"); return 1; } printf("what will happen\n"); return 0;
}

- 我们将
stdout关闭后,根据文件描述符的分配规则,新创建的文件fd为1。 - 我们观察结果发现,原本应该向显示器打印的消息直接向新创建的文件中写入。我们将这种现象称为输出重定向
>!!
三、输出重定向底层实现原理
在C中,printf函数只能向标准输出文件中输出消息,更准确的说:printf只认文件描述符为1对应的文件。
当我们关闭标准输出后,新创建的文件所分别的文件描述符fd为1。此时文件描述符表中,下标为1的数组内容由标准输出替换为新打开的文件log.txt。此时我们调用printf输出消息时,变为向log.txt文件中写入!!
所有重定向的本质就是修改特定文件fd的下标内容!!上层fd不变,下层fd指向的内容发生改变!

四、追加重定向(>>)
追加重定向和输出重定向基本相同,主要在于新创建文件的打开方式从w改为a。在底层上和输出重定向一样,都是将fd为1的下标内容替换为新文件即可!!!
int main()
{close(1); //将标准输出文件显示器关闭int fd = open("log.txt", O_CREAT | O_WRONLY | O_APPEND, 0666);//新创建文件,fd分配为1 if(fd < 0) { perror("open"); return 1; } printf("what will happen\n"); return 0;
}

五、输入重定向(<)
输入重定向<本质就是将待重定的文件内容替换到fd为0的下标位置。此时我们熟悉的scanf、fputs等函数读取方式会从键盘转变为新文件。即直接读取新文件中的内容
int main()
{close(0); //将显示器关闭 int fd = open("log.txt", O_RDONLY); //新创建文件fd为0if(fd < 0) { perror("open"); return 1; } char buffer[1024]; fread(buffer, 1, 1024, stdin);//从文件log.txt中读写信息 printf("stdin->fd:%d, %s\n", stdin->_fileno, buffer); return 0;
}

- 在上述代码执行过程中,没有出现光标等待我们从键盘上输入信息,而是直接将
log.txt中的信息输出,进一步说明了fd为0的下标内容被替换。
六、系统调用dup2
上述进行重定向时时进行的fd指向的内容替换,都需要我们手动先将对应的1、2、3号文件关闭,非常麻烦!为此,系统中提供了相关的系统调用接口:dup2。
#include <unistd.h>
int dup2(int oldfd, int newfd);//These system calls create a copy of the file descriptor oldfd
【实例】:
int main()
{int fd = open("log.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);dup2(fd, 1);printf("this is log.txt test\n"); return 0;
}

七、标准错误stderr存在意义
标准输出和标准错误都是向显示器上打印信息。既然都是向同一个硬件进行写入,为什么还需要标准错误的存在?
在项目实际运行过程中,bug是不可避免的。所以在日志中会记录很多正确信息和错误信息。而stderr存在的意义是将两者信息分开,将所有的错误信息全部写入标准错误文件中,从而降低排除的成本!!
【实例】:
- 下面我们通过输出
hello stdin和hello Stderr来模拟日志中的正确信息和错误错误信息!
int main()
{fprintf(stdout, "hello stdin\n"); fprintf(stderr, "hello Stderr\n");}
我们情况下,两者都在显示器上直接输出

我们也可以通过替换fd=1和fd=2的下标对应文件,来将两者信息分开,分别向两个文件中写入

- 我们也可以将两种信息全部打印到同一个文件中:
1>log.txt 2>&1。 这段代码的意思是先用log.txt文件fd中的内容替换fd=1下标中的内容,然后&1获得下标fd=1中保存的数据(即指向log.txt),最后将fd=2对应的内容用fd=1中的内容替换!!即fd=1和fd=2都指向了log.txt文件。 - 前面讲述的输入重定向、输出重定向、追加重定向都是简写的,原始版本应该和上面重定向一样,加上对应的fd。例如输出重定向
./myfile > log.txt是./myfile 1 > log.txt简写。
相关文章:
Linux文件:重定向底层实现原理(输入重定向、输出重定向、追加重定向)
Linux文件:重定向底层实现原理(输入重定向、输出重定向、追加重定向) 前言一、文件描述符fd的分配规则二、输出重定向(>)三、输出重定向底层实现原理四、追加重定向(>>)五、输入重定向…...
波搜索算法(WSA)-2024年SCI新算法-公式原理详解与性能测评 Matlab代码免费获取
声明:文章是从本人公众号中复制而来,因此,想最新最快了解各类智能优化算法及其改进的朋友,可关注我的公众号:强盛机器学习,不定期会有很多免费代码分享~ 目录 原理简介 一、初始化阶段 二、全…...
洛谷P1364 医院设置
P1364 医院设置 题目描述 设有一棵二叉树,如图: 其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,…...
哈希表的理解和实现
目录 1. 哈希的概念 (是什么) 2. 实现哈希的两种方式 (哈希函数) 2.1. 直接定址法 2.2. 除留余数法 2.2.1. 哈希冲突 3. 补充知识 3.1. 负载因子 3.2. 线性探测和二次探测 4. 闭散列实现哈希表 (开放定址法) 4.1. 开放定址法的实现框架 4.2. Xq::hash_table::insert…...
分治算法(Divide-and-Conquer Algorithm)
分治算法(Divide-and-Conquer Algorithm)是一种重要的计算机科学和数学领域的通用问题解决策略。其基本思想是将一个复杂的大规模问题分割成若干个规模较小、结构与原问题相似但相对简单的子问题来处理。这些子问题相互独立,分别求解后再通过…...
Java项目:基于ssm框架实现的实验室耗材管理系统(B/S架构+源码+数据库+毕业论文+答辩PPT)
一、项目简介 本项目是一套基于ssm框架实现的实验室耗材管理系统 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 二、技术实现 jdk版本:1.8 …...
如何通过专业的二手机店erp优化手机商家运营!
在数字化浪潮席卷全球的大背景下,手机行业作为科技发展的前沿阵地,正经历着前所未有的变革。对于众多手机商家而言,如何在这场变革中抢占先机,实现数字化转型,成为了摆在他们面前的一大难题。幸运的是,途渡…...
CentOS常见的命令及其高质量应用
CentOS是一个流行的、基于Red Hat Enterprise Linux(RHEL)的开源服务器操作系统。由于其稳定性和强大的性能,CentOS被广泛应用于各种服务器环境中。为了有效地管理和维护CentOS系统,熟悉并掌握其常见命令是非常重要的。本文将介绍…...
nodeJs用ffmpeg直播推流到rtmp服务器上
总结 最近在写直播项目 目前比较重要的点就是推拉流 自己也去了解了一下 ffmpeg FFmpeg 是一个开源项目,它提供了一个跨平台的命令行工具,以及一系列用于处理音频和视频数据的库。FFmpeg 能够执行多种任务,包括解封装、转封装、视频和音频…...
Django信号与扩展:深入理解与实践
title: Django信号与扩展:深入理解与实践 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 后端开发 tags: Django信号松耦合观察者扩展安全性能 第一部分:Django信号基础 Django信号概述 一. Django信号的定义与作用 Django信…...
使用Docker创建verdaccio私服
verdaccio官网 1.Docker安装 这边以Ubuntu安装为例Ubuntu 安装Docker,具体安装方式请根据自己电脑自行搜索。 2.下载verdaccio docker pull verdaccio/verdaccio3.运行verdaccio 运行容器: docker run -it -d --name verdaccio -p 4873:4873 ver…...
Spring 使用 Groovy 实现动态server
本人在项目中遇到这么个需求,有一个模块的server方法需要频繁修改 经阅读可以使用 Groovy 使用java脚本来时pom坐标 <dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy</artifactId><version>3.0.9</version>…...
oracle不得不知道的sql
一、oracle 查询语句 1.translate select translate(abc你好cdefgdc,abcdefg,1234567)from dual; select translate(abc你好cdefgdc,abcdefg,)from dual;--如果替换字符整个为空字符 ,则直接返回null select translate(abc你好cdefgdc,abcdefg,122)from dual; sel…...
算法-卡尔曼滤波之卡尔曼滤波的第二个方程:预测方程(状态外推方程)
在上一节中,使用了静态模型,我们推导出了卡尔曼滤波的状态更新方程,但是在实际情况下,系统都是动态,预测阶段,前后时刻的状态是改变的,此时我们引入预测方程,也叫状态外推方程&#…...
刘邦的创业团队是沛县人,朱元璋的则是凤阳;要创业,一个县人才就够了
当人们回顾刘邦和朱元璋的创业经历时,总是会感慨他们起于微末,都创下了偌大王朝,成就无上荣誉。 尤其是我们查阅史书时,发现这二人的崛起班底都是各自的家乡人,例如刘邦的班底就是沛县人,朱元璋的班底是凤…...
【Unity之FairyGUI】你了解FGUI吗,跨平台多功能高效UI插件
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:就业…...
基于51单片机的自动浇花器电路
一、系统概述 自动浇水灌溉系统设计方案,以AT89C51单片机为控制核心,采用模块化的设计方法。 组成部分为:5V供电模块、土壤湿度传感器模块、ADC0832模数转换模块、水泵控制模块、按键输入模块、LCD显示模块和声光报警模块,结构如…...
2024中国(重庆)商旅文化川渝美食暨消费品博览会8月举办
2024中国(重庆)商旅文化川渝美食暨消费品博览会8月举办 邀请函 主办单位: 中国航空学会 重庆市南岸区人民政府 招商执行单位: 重庆港华展览有限公司 展会背景: 2024中国航空科普大会暨第八届全国青少年无人机大赛在重庆举办ÿ…...
MacOS docker 安装与配置
orbstack 安装 官网: https://orbstack.dev 下载链接:Download OrbStack Fast, light, simple Docker Desktop alternative 选择是Apple M系列处理器, 或 Intel系列处理器 到这里就安装好了Orbstack软件,下面开始配置docker 下…...
【嵌入式大赛应用赛道】机械手臂
电机 进步电机:它的转动是以确定的步数进行的,只要计算好脉冲数量和频率,就可以准确预测和控制电机的转动角度、速度以及停止的位置 伺服电机:将输入的电信号(如电压或电流指令)转换成轴上的精确旋转运动…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
CppCon 2015 学习:REFLECTION TECHNIQUES IN C++
关于 Reflection(反射) 这个概念,总结一下: Reflection(反射)是什么? 反射是对类型的自我检查能力(Introspection) 可以查看类的成员变量、成员函数等信息。反射允许枚…...
