当前位置: 首页 > news >正文

【Linux】输入输出重定向

目录

一、概念

二、重定向的本质

三、系统调用接口dup和dup2

3.1 dup 

3.2 dup2


一、概念

在之前对Linux的学习中,我们有接触过一系列的重定向命令,例如 >、>>等

它们可以将一个命令的输出或输入重定向到其他地方,如echo命令用来将我们指定的文本打印到终端中,通过输出重定向就可以把原来要打印到终端的文本输出到其他的地方

例如我们可以通过重定向把echo要打印的内容重定向到某个文件中

像这样,通过控制数据的流向,让数据的目的地发生改变,即为重定向


二、重定向的本质

在学习重定向之前,我们需要先知道什么是文件描述符

【Linux】文件描述符 fd-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/Eristic0618/article/details/140838982?spm=1001.2014.3001.5501在前面的学习中,我们已经知道进程是通过文件描述符来访问文件的,而进程在打开一个文件时操作系统会给该文件分配一个当前最小的未使用的文件描述符。

所以假设我们把标准输出流关闭,那么1号文件描述符此时就是未被使用的状态

如果此时我们再打开一个文件,按理来说这个文件的文件描述符会分配为1

那么我们再向原来的标准输出流打印某些内容,这些内容会跑到哪里呢?

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{close(1); //关闭标准输出int fd = open("file.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666); //打开文件if(fd < 0){perror("open");return 1;}const char *msg = "hello Linux\n";int cnt = 5;while(cnt--) //循环5次{write(1, msg, strlen(msg)); //向原来的标准输出流打印}close(fd);return 0;
}

原本当我们向write函数传入1号文件描述符进行写入时会向显示器文件中写入。但现在当我们向1号文件描述符中打印的时候,显示器上什么也没有,而我们写入的内容已经写到了file.txt中。此时,我们就完成了对这些内容的重定向了

所以可以知道:重定向实际上就是改变某个文件描述符指向的文件

原本1号文件描述符对应标准输出流,但我们通过关闭标准输出流再创建新文件的方式让1号描述符重新分配给了我们的file.txt,所以向显示器打印的内容就重定向到了我们的file.txt中 

不过这种说法还不够准确,从内核的角度,应该说重定向就是修改文件描述符下标对应的file*指针


三、系统调用接口dup和dup2

dup和dup2都是Linux中用于实现重定向的系统调用接口,使用起来也并没有难度,不过二者之间有一些区别需要注意

3.1 dup 

向dup中传入一个文件描述符,会给我们返回一个新的文件描述符,传入的文件描述符和新的文件描述符指向的是同一个文件

例如:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{int newfd = dup(1);const char *msg = "hello Linux\n";write(newfd, msg, strlen(msg));printf("newfd: %d\n", newfd);return 0;
}

可以看到,我们向newfd中写入的内容被打印到了终端,说明newfd已经重定向到了标准输出中

3.2 dup2

dup2比dup多了一个参数,其中dup2会将newfd重定向到oldfd指向的文件,也就是将oldfd对应的file*指针拷贝到newfd对应的下标位置

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{int fd = open("file.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);dup2(fd, 1);const char *msg = "hello Linux\n";write(1, msg, strlen(msg));close(fd);
}

可以看到,因为1号文件描述符被重定向到了fd指向的文件,所以我们原本向标准输出中打印的内容并没有在终端中显示,而是被重定向到了file.txt中

除了对输出流进行重定向,我们也可以对输入流进行重定向,例如我们先向file.txt中写一些内容

然后用dup2将标准输入流重定向到文件对应的文件描述符

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{int fd = open("file.txt", O_RDONLY);dup2(fd, 0);char buffer[1024];ssize_t s = read(0, buffer, sizeof(buffer) - 1);if(s > 0){buffer[s] = '\0';printf("%s", buffer);}close(fd);
}

执行程序,此时虽然从0号文件描述符中读取数据,但因为已经被重定向到了fd指向的文件中,所以read会从文件中读取数据,最后将读取的内容打印出来

如有错误欢迎在评论区指出

完.

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • vue3组件之间通讯
  • 华为OD-D卷游戏分组
  • keepalived+lvs高可用负载均衡集群配置方案
  • MATLAB算法实战应用案例精讲-【数模应用】均值z 检验(附R语言、python和MATLAB代码实现)
  • Otter Go 语言编写的非竞争式缓存库
  • 8月5日学习笔记 glibc安装与安全用户角色权限
  • Postgresql数据库密码忘记的解决
  • 操作系统中的进程:深入解析与理解
  • Qt+TSC打印机调试
  • springboot疫情居家办公系统--论文源码调试讲解
  • AI驱动的招聘流程革新与挑战应对
  • HAProxy七层负载均衡配置方案
  • Linux的platform设备驱动框架
  • python中的迭代器、可迭代对象和生成器
  • 时序预测|基于变分模态分解-时域卷积-双向长短期记忆-注意力机制多变量时间序列预测VMD-TCN-BiLSTM-Attention
  • 《Java编程思想》读书笔记-对象导论
  •  D - 粉碎叛乱F - 其他起义
  • Elasticsearch 参考指南(升级前重新索引)
  • ERLANG 网工修炼笔记 ---- UDP
  • iOS | NSProxy
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • Javascripit类型转换比较那点事儿,双等号(==)
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • js递归,无限分级树形折叠菜单
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • Linux链接文件
  • 半理解系列--Promise的进化史
  • 初探 Vue 生命周期和钩子函数
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 开源地图数据可视化库——mapnik
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 每天10道Java面试题,跟我走,offer有!
  • 批量截取pdf文件
  • 一些关于Rust在2019年的思考
  • 怎么把视频里的音乐提取出来
  • Spring第一个helloWorld
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • ​力扣解法汇总946-验证栈序列
  • # AI产品经理的自我修养:既懂用户,更懂技术!
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (苍穹外卖)day03菜品管理
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (详细文档!)javaswing图书管理系统+mysql数据库
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • *算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿
  • .net MySql
  • .net SqlSugarHelper
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • [1204 寻找子串位置] 解题报告
  • [20171106]配置客户端连接注意.txt
  • [240621] Anthropic 发布了 Claude 3.5 Sonnet AI 助手 | Socket.IO 拒绝服务漏洞