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 下…...
【嵌入式大赛应用赛道】机械手臂
电机 进步电机:它的转动是以确定的步数进行的,只要计算好脉冲数量和频率,就可以准确预测和控制电机的转动角度、速度以及停止的位置 伺服电机:将输入的电信号(如电压或电流指令)转换成轴上的精确旋转运动…...
PPTX判断包含图表id
PPTX判断包含图表id ############################20250915判断是否包含图表################################################## i0 for shape in prs.slides[1].shapes:if shape.HasChart:print(fi:{i}包含图表)ii1 ############################20250915判断是否包含图表##…...
中美Agent生态的路径差异——《重构与崛起——OpenClaw时代的中国Agent产业生态报告》解读三
易观分析:面对OpenClaw掀起的全球AI Agent技术浪潮,中美两国走出截然不同的发展路径。美国生态追求底层框架与协议的原创定义;而中国生态以应用驱动、平台绑定和合规先行为核心逻辑,快速将前沿技术转化为可落地的商业现实。这两条…...
RV1126平台GC2053摄像头驱动移植与VLC视频流调试实战
1. RV1126与GC2053摄像头驱动移植实战 最近在一个人脸识别项目中遇到了一个有趣的技术挑战:需要在RV1126开发板上为GC2053红外摄像头添加驱动支持。这个看似简单的任务实际上涉及硬件连接、内核配置、设备树修改等多个环节。作为嵌入式开发者,我花了三天…...
OpenWebUI智能管道:连接本地AI模型与高性能推理后端
1. 项目概述:一个连接OpenWebUI与本地AI模型的智能管道最近在折腾本地大语言模型(LLM)的朋友,估计都绕不开OpenWebUI(原名Ollama WebUI)这个项目。它提供了一个极其美观、功能强大的Web界面,让我…...
基于Vercel AI SDK与Next.js 14构建智能编程助手:从架构到部署实战
1. 项目概述:一个面向开发者的AI编程助手脚手架最近在GitHub上看到一个挺有意思的项目,叫vercel-labs/coding-agent-template。光看名字,你大概能猜到,这是一个跟AI编程助手相关的模板项目。没错,它本质上是一个预先配…...
Manus Open Claw开源技能库:构建可共享的机器人抓取解决方案
1. 项目概述:一个面向机器人抓取的开源技能库最近在机器人抓取领域,一个名为simpliolabs/manus-open-claw-skill-hunter-and-developer的项目引起了我的注意。乍一看这个标题,信息量不小,它融合了“开放爪具”、“技能猎人”和“开…...
AI智能体技能开发实战:从awesome-agent-skills到高效智能体构建
1. 项目概述:从技能清单到智能体构建的实战指南最近在折腾AI智能体(Agent)开发的朋友,估计都绕不开一个名字:awesome-agent-skills。这个由VoltAgent维护的开源项目,乍一看就是个GitHub上常见的“Awesome”…...
别再让电池充不满!用CN3791芯片设计太阳能充电电路,这几个调试坑我帮你踩了
太阳能充电电路实战:CN3791芯片调试避坑指南 当阳光洒在太阳能板上,理论上我们应该获得源源不断的清洁能源。但现实往往比理想骨感得多——尤其当你发现精心设计的CN3791充电电路始终无法将锂电池充满时。这不是芯片的错,而是我们在参数设置和…...
中国500万医生的新AI:顶刊独家联手,卷的就是证据源
金磊 发自 杭州量子位 | 公众号 QbitAI很反差。明明是一场AI的发布会,台下却坐满了医学界的大佬们:有北大、清华的,有浙江、上海的,甚至医学顶刊BMJ集团的主编都来围观了……△图片由AI生成为啥会这样?因为阿里健康正式…...
批量处理二维码图片,真的需要联网吗?这款离线高效工具给你答案!
批量处理二维码图片,真的需要联网吗?这款离线高效工具给你答案! 【免费下载链接】QrScan 离线批量检测图片是否包含二维码以及识别二维码 项目地址: https://gitcode.com/gh_mirrors/qrs/QrScan 想象一下这个场景:公司市场…...
