深入剖析Linux重定向
2021/12/2 7:08:07
本文主要是介绍深入剖析Linux重定向,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
本文探讨一下Shell 是如何借助文件描述符实现重定向的。
Linux 系统每次读写文件的时候,都从文件描述符下手,通过文件描述符找到文件指针,然后进入打开文件表和 i-node 表,这两个表里面才真正保存了与打开文件相关的各种信息。试想一下,如果我们改变了文件指针的指向,不就改变了文件描述符对应的真实文件吗?比如文件描述符 1 本来对应显示器,但是我们偷偷将文件指针指向了 log.txt 文件,那么文件描述符 1 也就和 log.txt 对应起来了。文件指针只不过是一个内存地址,修改它是轻而易举的事情。文件指针是文件描述符和真实文件之间最关键的“纽带”,然而这条纽带却非常脆弱,很容易被修改。Linux 系统提供的函数可以修改文件指针,比如 dup()、dup2();Shell 也能修改文件指针,输入输出重定向就是这么干的。
对,没错,输入输出重定向就是通过修改文件指针实现的!更准确地说,发生重定向时,Linux 会用文件描述符表(一个结构体数组)中的一个元素给另一个元素赋值,或者用一个结构体变量给数组元素赋值,整体上的资源开销相当低。发生重定向的时候,文件描述符并没有改变,改变的是文件描述符对应的文件指针。对于标准输出,Linux 系统始终向文件描述符 1 中输出内容,而不管它的文件指针指向哪里;只要我们修改了文件指针,就能向任意文件中输出内容。以下面的语句为例来说明:
echo "log test" 1>log.txt
文件描述符表本质上是一个结构体数组,假设这个结构体的名字叫做 FD。发生重定向时,Linux 系统首先会打开 log.txt 文件,并把各种信息添加到 i-node 表和文件打开表,然后再创建一个 FD 变量(通过这个变量其实就能读写文件了),并用这个变量给下标为 1 的数组元素赋值,覆盖原来的内容,这样就改变了文件指针的指向,完成了重定向。
Shell 对文件描述符的操作
在shell中,>
是输出重定向符号,<
是输入重定向符号;更准确地说,它们应该叫做文件描述符操作符。> 和 < 通过修改文件描述符改变了文件指针的指向,所以能够实现重定向的功能。除了 > 和 <,Shell 还是支持<>
,它的效果是前面两者的总和。
分类 | 用法 | 说明 |
---|---|---|
输出 | n>filename | 以输出的方式打开文件 filename,并绑定到文件描述符 n。n 可以不写,默认为 1,也即标准输出文件。 |
n>&m | 用文件描述符 m 修改文件描述符 n,或者说用文件描述符 m 的内容覆盖文件描述符 n,结果就是 n 和 m 都代表了同一个文件,因为 n 和 m 的文件指针都指向了同一个文件。 因为使用的是 > ,所以 n 和 m 只能用作命令的输出文件。n 可以不写,默认为 1。 |
|
n>&- | 关闭文件描述符 n 及其代表的文件。n 可以不写,默认为 1。 | |
&>filename | 将正确输出结果和错误信息全部重定向到 filename。 | |
输入 | n<filename | 以输入的方式打开文件 filename,并绑定到文件描述符 n。n 可以不写,默认为 0,也即标准输入文件。 |
n<&m | 类似于 n>&m,但是因为使用的是< ,所以 n 和 m 只能用作命令的输入文件。n 可以不写,默认为 0。 |
|
n<&- | 关闭文件描述符 n 及其代表的文件。n 可以不写,默认为 0。 | |
输入和输出 | n<>filename | 同时以输入和输出的方式打开文件 filename,并绑定到文件描述符 n,相当于 n>filename 和 n<filename 的总和。。n 可以不写,默认为 0。 |
【实例1】前面的文章中提到了下面这种用法:
command >file 2>&1
它省略了文件描述符 1,所以等价于:
command 1>file 2>&1
这个语句可以分成两步:先执行1>file
,让文件描述符 1 指向 file;再执行2>&1
,用文件描述符 1 修改文件描述符 2,让 2 和 1 的内容一样。最终 1 和 2 都指向了同一个文件,也就是 file。所以不管是向 1 还是向 2 中输出内容,最终都输出到 file 文件中。这里需要注意执行顺序,多个操作符在一起会从左往右依次执行。对于上面的语句,就是先执行1>file
,再执行2>&1
;如果写作下面的形式,那就南辕北辙了:
command 2>&1 1>file
Shell 会先执行2>&1
,这样 1 和 2 都指向了标准错误输出文件,也即显示器;接着执行1>file
,这样 1 就指向了 file 文件,但是 2 依然指向显示器。最终的结果是,正确的输出结果输出到了 file 文件,错误信息却还是输出到显示器。
【实例2】一个比较奇葩的重定向写法。
echo "shell log 2" 10>log.txt >&10
先执行10>log.txt
,打开 log.txt,并给它分配文件描述符 10;接着执行>&10
,用文件描述符 10 来修改文件描述符 1(对于>
,省略不写的话默认为 1),让 1 和 10 都指向 log.txt 文件,最终的结果是向 log.txt 文件中输出内容。这条语句其实等价于echo "C语言中文网" >log.txt
,我之所以写得这么绕,是为了让大家理解各种操作符的用法。文件描述符 10 只用了一次,我们在末尾最好将它关闭,这是一个好习惯。
echo "shell log 3" 10>log.txt >&10 10>&-
这篇关于深入剖析Linux重定向的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法