首页 > 代码库 > Linux之数据流重导向

Linux之数据流重导向

       其实一开始绕进文件描述符这个大坑里去了,越挖越深,什么系统文件表,内存索引节点,VFS等等都一下子冒了出来,而我暂时还没那么多精力搞定所有,于是只能屏蔽底层的一些细节,暂且当作黑盒子,来日再挖。。。

1、Linux系统中,一切资源都被视为文件,包括放在磁盘上的各种文档图片,甚至各种设备。文件是Linux组织计算机硬件资源的基本逻辑单位。

2、进程,具体的说就是我们敲的所有命令,本质上就是在操作一系列文件,接着产生一系列结果。比如常用的ls命令,后面不加参数时,操作对象默认为是当前目录(目录也是文件——目录文件),然后把该目录下的所有文件的名字输出到屏幕上(屏幕也是文件啊衰~)。

3、操作的结果有两种,一种是正确的结果,另一种是错误的结果。Linux把前者称为标准输出,其文件描述符是1;后者称为标准错误输出,对应的文件描述符是2。这两类结果信息是分开的。默认情况下,这两类信息都会输出到屏幕上,让操作着直接、立即看到,然后阅后即焚。如果我们想把这两类信息保存下来方便以后复习,就需要用到重导向了。

4、比如我的家目录是这样子的:

m@localhost:~$ ls
desktop  program  wine-git  公共  模板  视频  图片  文档  下载  音乐  桌面

默认情况下结果直接打印到屏幕上。

那现在我想把结果保存到file1这个文件中,就可以这样:

m@localhost:~$ ls > file1


ls一下,就会发现当前目录多了一个文件file1:

m@localhost:~$ ls
desktop  file1  program  wine-git  公共  模板  视频  图片  文档  下载  音乐  桌面

这里需要注意:1)如果当前目录没有file1文件,那么它就会被新建;如果已经存在一个名叫file1的文件,那么之前的内容会被覆盖。

                            2)> 前面如果没有数字,则默认为1,即标准输出。

看一下file1的内容:

m@localhost:~$ cat file1 
desktop
file1
program
wine-git
公共
模板
视频
图片
文档
下载
音乐
桌面


这里要注意的是,file1文件名本身也在file1的内容里,这说明了什么呢?对的,顺序问题。


5、我们试一下这样:

m@localhost:~$ ls program/ nothing
ls: 无法访问nothing: 没有那个文件或目录
program/:
google-chrome-stable_current_i386.rpm

显然,把nothing作为ls的参数就会显示错误,因为当前目录下并没有这个文件。那么现在把这两个信息分别保存在right和wrong文件中,就可以这样:

m@localhost:~$ ls program/ nothing >right 2>wrong


检查一下:

m@localhost:~$ cat right 
program/:
google-chrome-stable_current_i386.rpm

m@localhost:~$ cat wrong 
ls: 无法访问nothing: 没有那个文件或目录


6、那我想把正确信息和错误信息保存在同一文件中呢?可以这样:

m@localhost:~$ ls program/ nothing &> all


检查一下:

m@localhost:~$ cat all 
ls: 无法访问nothing: 没有那个文件或目录
program/:
google-chrome-stable_current_i386.rpm


7、还有一种方法也可以把正确信息和错误信息保存在同一文件中:

m@localhost:~$ ls program/ nothing > all 2>&1

解释一下这种用法:首先,> all就是1> all,即把标准输出重定向到all文件中;然后2>表示把标准错误也重定向,但是重定向到哪儿呢?那么&1就表示重定向到文件描述符1所指向的那个文件,这种用法其实类似于变量,为了方便而已。

检查一下:

m@localhost:~$ cat all
ls: 无法访问nothing: 没有那个文件或目录
program/:
google-chrome-stable_current_i386.rpm


显然上面的用法和这个是一样的道理:

m@localhost:~$ ls program/ nothing 2> all 1>&2


一开始我也不明白,为什么像这样就不行呢?

m@localhost:~$ ls program/ nothing 2> all 1>all

多直观多明了啊,但是是错的。。。

m@localhost:~$ cat all
program/:
google-chrome-stable_current_i386.rpm
?录

原因嘛。。。据说是因为标准输出和标准错误交替写入all文件时,由于没有规定谁先谁后,于是就乱码。而2> all 1>&2这种办法,本质上是调用dup(2)这个系统函数复制了前面的行为,总之很复杂,先不管了。


8、如果这样会怎样?

m@localhost:~$ ls program/ nothing  1>&2 2> all

自己试试吧,还是顺序问题。


Linux之数据流重导向