【linux二三轶事】重定向是啥?文件描述符是啥?

【前言】

写这篇文章的原因,是因为我在工作中遇到重定向和fd的时候,被这厮折磨的够呛。现在终于战胜了他们,当然要奏一首凯歌,率土同庆啦!

在开启正文之前,我们必须要先明白几个关键点,这对于理解后面的文章颇有帮助。而且,在阅读后面的文章时,我们也会加深对这些关键点的理解。

首先,我们要知道在linux中,一切皆文件。其实,在linux中不仅我们创建的txt,tar,sh是文件,其他的东西比如:目录,设备(字符设备,块设备),进程,线程,套接字,管道都是文件。我们所熟知的键盘和显示器属于字符设备,所以在linux中,键盘和显示器也是文件

第二,我们和计算机的交互,本质上就是输入和输出。我们通过输入命令告诉计算机要做哪些事情,然后计算机处理后,会通过打印在屏幕或者输出文件的方式来告诉我们,它输出了什么。所以,有了第一条关键点之后,我们不难理解,linux上所有命令的处理其实可以简化为输入文件 -> 命令 -> 输出文件的形式。比如 ls,它的默认输出文件其实就是屏幕。

第三,还有一个难啃的骨头,它叫文件描述符fd(file descriptor)。fd有很多俗称,有人叫它文件句柄,也有人叫它文件引用,甚至还有人叫它通道。我觉得都可以,其实fd本身不是文件,而是一个符号,它可以指向某个文件。由此看来,我们可以把上面的形式升级为[文件描述符]输入文件->命令->[文件描述符]输出文件的形式。而实际的情况,也大抵如此。

好了,啰里啰嗦了这么多,观众老爷们该不高兴了,我们赶紧进入正文吧!

【正文】

1. linux标准

实际上,linux已经规定好了一些fd的用处。如下:

fd 缩写 描述 默认指向文件
0 stdin 标准输入 键盘
1 stdout 标准输出 屏幕
2 stderr 标准错误输出 屏幕

在linux中,有一个exec命令可以改变文件描述符所指向的文件。我们可以尝试一下,把标准输出fd1指向的文件从屏幕文件改成一个普通文件,看看会有什么效果。

exec 1>1.txt
ls

执行完上面的命令,我们会发现ls并没有打印在屏幕上,这时候我们再打开一个终端,打开1.txt文件。是不是会出现刚才ls的内容呢?
顺便提一下一个知识点,有的时候我们会看到这样的命令

exec 6<>1.txt

实际上这条命令不仅是让fd6指向1.txt,而且还以读写的方式打开了1.txt文件。>表示只写,<表示只读,<>表示读写。

2. 重定向

关于重定向的话,我们主要理解> < >> << 就行。其中,<和<<属于输入重定向,>和>>属于输出重定向。
那我们如何理解重定向呢?基于我们总结的关键点[文件描述符]输入文件->命令->[文件描述符]输出文件,改变方向其实就是改变文件描述符(fd)所指向的文件
我们来看一个常见的例子:

echo "xiaoma" > 1.txt

本来正常情况下echo后面的字符串是会打印到屏幕上,但是现在这些字符串跑到了1.txt文件中,这就是重定向。
现在我们来仔细分析一下这个过程,echo命令的输出本来是标准输出,也就是fd1(默认指向屏幕文件),后来经过重定向,fd1就指向了1.txt文件。可能大家会有疑惑,我怎么没看到fd1从屏幕文件重定向到了1.txt。这是因为> 1.txt 就等于 1> 1.txt,fd1作为标准输出可以省略不写。不信大家可以试一下,肯定是一样的效果:

echo "xiaoma" 1> 1.txt  #注意1和>之间不能有空格,但是>和1.txt之间可以有

与它一样的还有标准输入0,当0在<左边的时候也是可以省略不写。

3. &的作用

有的时候,我们会看到这样的命令

exec 3<>1.txt
echo "xiaoma" >&3

这里第一句话我们应该明白,就是让fd3指向1.txt。对于后面一句话,他其实是把fd1重定向到了fd3,也就是最终fd1实际上指向了1.txt文件。
可能我们会有疑惑,为什么1不加&,而3要加&。实际上,这就是规定,在重定向符号左边不用加&,数字表示的就是fd,但是重定向符号右边如果不加&,3就变成了一个文件,而不再是fd3。你可以试试不加&,看看"xiaoma"是不是输出到了一个名叫3的文件中。

4. 1>/dev/null

我们应该会经常看到这样的命令吧,

echo "xiaoma" 1>/dev/null  2>&1 

如果大家是从上往下读这篇文章,想必已经知道了答案。如果跳着读,可能就不清楚了。其实/dev/null,表示空设备文件,它会丢弃一切写入它的文件。这句话的意思是说,我把fd1指向/dev/null,然后我再把fd2指向fd1,最终fd2也就指向了/dev/null。作用不言而喻:所有的输出,不管是标准输出还是错误输出,我都不要啦。

【后记】

看到这,我相信观众老爷们对重定向和文件描述符有一个新的了解了吧。如果有的话,我当然幸甚乐哉。如果没看懂的话,观众老爷们也可以随时来骚扰,我当尽我所能。
最后,观众老爷们如果看的还开心的话,临走时不妨点个赞,点个关注,小弟在此多谢各位。

你可能感兴趣的:(【linux二三轶事】重定向是啥?文件描述符是啥?)