【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会从文件中读取数据,最后将读取的内容打印出来

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

完.

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源应用:AI监测如何成为社会安全的智能盾牌

社会背景 随着社会的快速发展&#xff0c;社会安全管理正站在一个新时代的门槛上。社会对安全管理的需求不断增长&#xff0c;传统的安全措施已难以满足现代社会的需求。AI技术以其独特的数据处理和模式识别能力&#xff0c;正在成为我们社会安全的智能盾牌。 AI大模型识别功能…

3.js - 物理引擎终极

import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls import gsap from gsap // 导入动画库 import * as dat from dat.gui // 导入dat.gui// 导入 cannon-es 引擎 import * as CANNON from cannon-es// -----------------…

探索GPT-4o mini:开启AI驱动的开发新时代

文章目录 GPT-4o mini&#xff1a;小身材&#xff0c;大能量成本与效能的完美平衡 AI辅助开发&#xff1a;从构想到现实自动化文档编写智能代码审查 提升创新能力&#xff1a;AI驱动的新常态模型驱动的设计思维 社区共享与合作知识共享的重要性 未来展望&#xff1a;AI与人类的…

<数据集>agv仓储机器人识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;1514张 标注数量(xml文件个数)&#xff1a;1514 标注数量(txt文件个数)&#xff1a;1514 标注类别数&#xff1a;3 标注类别名称&#xff1a;[G1PB2000_Paleteira_AGVS BYD, G1RB5000, AGV-P] 序号类别名称图片数…

6自由度机械手DH坐标系建立

一、建立机械臂DH坐标系 Z为转动关节的转轴&#xff0c;Xi垂直于关节轴i和i1所在的平面&#xff0c;则根据上述方法可以建立坐标系如下图&#xff1a; 二、DH参数表 DH参数设定&#xff1a;机器人的每个连杆可以用4个运动学参数表示&#xff0c;DH法建立坐标系&#xff0c;xi-…

[开端]如何看待“低代码”开发平台的兴起

如何看待“低代码”开发平台的兴起&#xff1f; 近年来&#xff0c;“低代码”开发平台如雨后春笋般涌现&#xff0c;承诺让非专业人士也能快速构建应用程序。这种新兴技术正在挑战传统软件开发模式&#xff0c;引发了IT行业的广泛讨论。低代码平台是提高效率的利器&#xff0…

[开端]JAVA抽象类使用到redis观察着

一、绪论 当redis内容发生变化时需要通知一些观察者做一些动作怎么做&#xff1f; 二、JAVA抽象类 public abstract class AbstractRedisChangeListener {public abstract void change(String key, String value, String crudType); }使用abstract进行修饰一个类 其中抽象类…

SpringBoot中如何自定义自己的过滤器Filter(简易版)

本文不再说SpringMVC中的写法&#xff0c;毕竟现在项目都是SpringBoot&#xff0c;我们还是尽量使用SpringBoot的写法&#xff0c;首先了解一下Filter。 说白了&#xff0c;就是在请求到达服务器之前进行拦截&#xff0c;一般使用场景是拦截登录进行权限校验&#xff0c;当然一…

安装python+python的基础语法

安装python python2为内置&#xff0c;安装python3----3.6.8 最新安装3.12使用源码安装 1.查看yum源&#xff0c;epel [rootpython01 ~]# yum list installed |grep epel 2.安装python3 [rootpython01 ~]# yum -y install python3 3.查看版本 [rootpython01 ~]# python…

Android Studio Gradle多渠道打包

原理使用Android Studio打一次渠道包&#xff0c;用反编译工具反编译后&#xff0c;修改渠道信息重新编译 准备文件 分渠道配置文件&#xff1a;channel.txt ↓ # 多渠道配置里“统计平台”、“市场名称”、“渠道编号”分别代表什么意思&#xff1f; # 统计平台&#xff1a;…

AT32F421驱动BLDC 配合上位机控制与调参

AT32F421驱动BLDC 配合上位机控制与调参 &#x1f527;AT32 电机控制与调参上位机软件&#xff1a;ArteryMotorMonitor&#xff1a;https://www.arterytek.com/cn/support/motor_control.jsp?index0&#x1f33f;测试电机参数&#xff1a;2204-12N14P&#xff0c;无感BLDC&…

LVS(Linux Virtual Server)

简介 LVS&#xff08;Linux Virtual Server&#xff09;是一个高性能的开源负载均衡解决方案&#xff0c;它通过在Linux内核中实现IPVS&#xff08;IP Virtual Server&#xff09;模块来提供负载均衡功能。LVS能够将外部请求根据特定的算法分发到后端的多个服务器上&#xff0c…

百度文心一言API调用,千帆大模型获取API Key和API Secret图解

百度文心一言大模型调用教程&#xff0c;获取文心一言API Key和API Secret的方法&#xff0c;码笔记mabiji.com告诉大家在百度智能云的千帆大模型平台创建应用&#xff0c;即可获取文心一言的API Key和API Secret&#xff0c;详细流程如下&#xff1a; 1、在百度智能云的千帆大…

gitlab项目添加新成员

gitlab项目添加新成员 1、进入项目&#xff0c;找到settings----->点击Members 2、手动输入要添加成员的账号或者搜索&#xff0c;最后点击Add to project就可以了 choose a role permission 是为要添加的成员选择角色权限 补充&#xff1a; ‌Maintainer&#xff1a;拥…

同态加密和SEAL库的介绍(八)性能

本篇会对比三种加密方案&#xff0c;同时每种方案配置三种参数。即九种情况下的各个操作的性能差异&#xff0c;为大家选择合适的方案和合适的参数提供参考。表格中所有时长的单位均为微妙&#xff0c;即 。 当然数据量比较大&#xff0c;为了方便大家查找&#xff0c…

[BSidesCF 2019]Kookie1

打开题目&#xff0c;看到 根据提示&#xff0c;账号&#xff1a;cookie。密码&#xff1a;monster。试一下登录&#xff0c;登陆成功 抓包看看信息 根据提示&#xff0c; 看一下返回包 账号要加username要改成admin&#xff0c;改一下试试 构造cookie 直接得到flag flag{c…

Redis远程字典服务器(3)——常用数据结构和单线程模型

目录 一&#xff0c;常用数据结构 1.0 前言 1.1 string 1.2 hash 1.3 list 1.4 set 1.5 zset 1.6 演示 二&#xff0c;关于单线程模型 2.1 关于Redis的单线程 2.2 Redis为什么快 一&#xff0c;常用数据结构 1.0 前言 Redis是采用键值对的方式来存储数据的&#…

探索算法系列 - 前缀和算法

目录 一维前缀和&#xff08;原题链接&#xff09; 二维前缀和&#xff08;原题链接&#xff09; 寻找数组的中心下标&#xff08;原题链接&#xff09; 除自身以外数组的乘积&#xff08;原题链接&#xff09; 和为 K 的子数组&#xff08;原题链接&#xff09; 和可被 …

Java—抽象类和接口 (´▽`)ノ

目录&#xff1a; 一、抽象类&#xff1a; 1、概念: 在面向对象中&#xff0c;所有对象都是由类来创建的&#xff0c;但是呢&#xff0c;并不是所有的类都用来创建类&#xff0c;如果一个类不能描述一个具体的对象&#xff0c;那么这个类就是抽象类。 可以看到&#xff0c;我们…

kotlin简介

Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言&#xff0c;被称之为 Android 世界的Swift&#xff0c;由 JetBrains 设计开发并开源。 Kotlin 可以编译成Java字节码&#xff0c;也可以编译成 JavaScript&#xff0c;方便在没有 JVM 的设备上运行。 在Google I/O 2017…