输出重定向

简介: 输出重定向

从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中)

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

相关文章
|
6月前
|
Shell 数据处理
Shell编程中,输入/输出重定向和管道
Shell编程中,输入/输出重定向和管道
45 2
|
6月前
|
安全 Linux 数据处理
|
数据挖掘 Linux
如何在 Linux 中将输出重定向到文件和标准输出?如此简单!
如何在 Linux 中将输出重定向到文件和标准输出?如此简单!
1583 0
如何在 Linux 中将输出重定向到文件和标准输出?如此简单!
|
机器学习/深度学习 存储 监控
sed命令(超详细)
是一种流编辑器,它是文本处理中非常好的工具,能够完美的配合正则表达式使用,功能不同凡响。 处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命 令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复, 直到文件末尾。
209 0
|
MySQL 关系型数据库 Perl