输出重定向

简介: 输出重定向

从ls > log.txt谈起

ls > log.txt是什么意思?我们先来看看现象

我们当前所处的目录有以下文件/文件夹

接着我们执行 ls > log.txt

我们发现:

当前目录下创建了log.txt文件,log.txt存储了ls命令执行的结果。这是怎么一回事呢?

我们把这种现象成为“输出重定向”

以ls>log.txt为例,他把本该输出到显示器的内容输出到了log.txt文件里了。所以才会发生上述现象。

那么它是怎样实现的呢?

让我们来看看下面这段代码:

open:

【open函数是一个系统调用接口,其功能是打开或有可能创造一个文件/设备,其函数原型如下(open是一个重载函数,下面这个open用来创建文件),

解释一下这几个参数:

pathname:传一个文件名

flags:以哪些方式打开文件(O_WRONLY(只读),O_CREAT(不存在则创建文件)O_TRUNC(每次打开文件时清空文件)等等)

mode:设置文件权限

返回值:

返回一个文件描述符,它是非负的整数,被用于read、write等系统调用。成功返回的文件描述符会是最小的、当前没有为该进程所打开的文件描述符

write:

【write是往一个文件描述符(实际是往这个描述符随对应的文件)中写入buf所指向的内容,至多count个字节

函数原型:

返回值:

成功写入的字节个数,失败返回-1.

这段代码在干什么:

是往log1.txt文件里面写入msg指向的内容,程序运行结果如下

我们可以看到,hello,linux的内容已经被写入到log1.txt里了

接下来我们将上述代码稍作改变。

把fd,换成了1

再次编译运行

hello,linux直接打印在了显示器上。据此我们可以猜测,内容写到哪里,与这个fd有很大关系。

fd是什么:

第一句话的意思是,将buf指向的至多count个字节内容写到由文件描述符fd指代的文件中去,也就是说fd是对文件的指代,相当于一个映射,比如fd等于1,1号文件对应显示器文件

操作系统会默认将0 1 2分配给键盘文件、显示器文件、显示器文件,也就是说0 1 2默认是打开的,且分别存储了这三个文件的地址

fd           文件

0           键盘文件

1           显示器文件

2           显示器文件

下图阐述了操作系统是如何管理文件的

在pcb中(为什么在pcb中,因为文件常常是由进程进行访问的)有一个struct files_struct类型的指针,顾名思义,它指向struct files_struct类型的结构体,在该结构体内,存储了一个指针数组,这个数组的下标就是我们说的fd,数组元素就是指向文件结构体的地址。(进程每访问一个文件就创建该文件的结构体,并在struct files_struct中为它分配一个数组下标,即fd)

回答开头说的 ls>log.txt的实现原理:

把1所对应的显示器文件地址更改成log.txt文件地址,这个就是它实现的基本原理

那么要如何实现“更改”呢?这需要用到我们的系统调用接口dup2,它可以实现我们的期望。

(dup2,将oldfd指向的内容覆盖到newfd指向的内容,即newfd指向的内容会变成oldfd指向的内容

)

请看如下2段代码

他们的区别就是第二段代码加了dup2,将1所在文件地址改成fd所在文件地址。

运行结果

代码1(写在显示器)

代码2(将本该写到显示器的内容写到了log1.txt中)

由此,通过偷梁换柱,实现了开头所讲的效果。

相关文章
|
缓存 运维 Shell
幻兽帕鲁爆内存优化方案
最近有很多小伙伴反馈说4C16G的服务器玩时间久了经常出现内存过满自动重启的情况,现在总结下linux和windows系统下怎么进行优化。
|
11月前
|
机器学习/深度学习 数据采集 人工智能
AI在用户行为分析中的应用:实现精准洞察与决策优化
AI在用户行为分析中的应用:实现精准洞察与决策优化
1506 15
|
前端开发 C# Windows
解决Gradle下载缓慢的问题,将-bin改为-all
【11月更文挑战第15天】PropertyGrid 是一种用户界面组件,允许用户直观地查看和编辑对象属性。WPF 中虽无内置控件,但可通过组合 Expander 和 DataGrid 实现基本功能,或使用 PropertyTools 等第三方库获得更强大的功能。
292 1
|
存储 IDE Java
Java“ClassFormatError”解决
Java中的“ClassFormatError”是一个运行时异常,通常发生在类文件格式不正确或被篡改时。本文将介绍该错误的常见原因及解决方法,帮助开发者快速定位并解决问题。
550 2
|
传感器 数据采集 算法
LabVIEW中进行步进电机的位置控制
LabVIEW中进行步进电机的位置控制
290 20
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的反诈科普平台的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的反诈科普平台的详细设计和实现(源码+lw+部署文档+讲解等)
263 0
|
域名解析 缓存 前端开发
函数计算产品使用问题之添加的插件中只有部分显示成功,是什么导致的
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
148 0
|
移动开发 小程序 API
uniapp中uview组件库丰富的ActionSheet 操作菜单使用方法
uniapp中uview组件库丰富的ActionSheet 操作菜单使用方法
913 1
|
NoSQL 中间件 MongoDB
MongoDB查询过程
【7月更文挑战第3天】
126 0