在linux中,从man read的帮助手册中看到了read能从文件描述符中读取内容,那么这个文件描述符到底是什么?
-u fd Read input from file descriptor fd.
在shell中,大家应该对stdin,stdout,stderr有所了解,就是输入输出流的重定向中经常出现的那个 &1 &2.
shell将stdout指向 1 这个数字,将stdin指向 2 这个数字,将stdin指向 0 这个数字。
当然,用户可以自己定义,将这些重新指定这些数字的指向。
为了方便,我不使用系统默认的0,1,2这三个数字,我使用3来演示。
在/tmp 目录下有文件 a :
[root ~ ]$ cat /tmp/a AAA b c d aaa [root ~ ]$
将这个文件指向数字3:
[root ~ ]$ exec 3</tmp/a
这时候,3就成了文件 /tmp/a 的文件描述符。而在linux中一切皆为文件,所以上面提到的 0,1,2 也是对应文件的文件描述符。
现在,可以使用文件描述符读取文件:
[root ~ ]$ cat <&3 AAA b c d aaa [root ~ ]$
只要在文件描述符前加上”&“符号即可使用(学过C语言的是不是觉得和指针很像?)。
在shell中重定向的我们会用到 "<",">",">>",在上面的例子中,我们使用的是"<",所以我们只能从/tmp/a 中读取内容,要写入内容就是:
[root /tmp ]$ exec 3>/tmp/a
要读写文件是:
[root /tmp ]$ exec 3<>/tmp/a
要追加内容是:
[root /tmp ]$ exec 3>>/tmp/a
在某个文件描述符使用完后,关闭该描述符:
[root /tmp ]$ exec 3>&- #关闭写入 [root /tmp ]$ exec 3<&- #关闭读取 [root /tmp ] exec 3<>&- #这样写报错了,要分开写 -bash: syntax error near unexpected token `&'
在指定文件描述符的时候,"<",">",">>"这些符号的前面(和数字之间)不能有空格,否则就不是指定文件描述符了;这些符号后面可以有空格(有例外,后面提到)
[root ~ ]$ exec 3</tmp/a #没有空格可以 [root ~ ]$ exec 3< /tmp/a #后面有空格可以 [root ~ ]$ exec 3 </tmp/a #前面有空格,奇怪的事情发生了 :) -bash: exec: 3: not found [root ~ ]$ logout
符号后加空格有时候也会出错:
[root /tmp ]$ exec 3> &- #在关闭文件描述符的时候,后面跟空格也出错了 -bash: syntax error near unexpected token `&'
所以建议大家,这些符号前后都不要跟空格
文件描述符并不是session独立的,但也不是session之间完全共享的:
[root /tmp ]$ w #当前系统共登录了两个用户,都是root 15:10:41 up 102 days, 5:34, 2 users, load average: 0.04, 0.01, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 172.16.100.108 14:25 0.00s 0.10s 0.00s w root pts/1 172.16.100.108 15:10 3.00s 0.05s 0.05s -bash [root /tmp ]$ #一个root在/tmp 目录,另一个在/root 目录,以便区分 [root ~ ]$ cat /tmp/a AAA b c d aaa [root ~ ]$ cat /tmp/b #两个文件的内容 haha [root ~ ]$ #在一个session中定义文件描述符3 [root /tmp ]$ exec 3</tmp/a [root /tmp ]$ cat <&3 AAA b c d aaa #之后在另一个session使用 [root ~ ]$ cat <&3 -bash: 3: Bad file descriptor #再返回第一个session中使用 [root /tmp ]$ cat <&3 [root /tmp ]$ #结果为空
其他session不仅不能使用,一旦使用还会对原session造成影响,所以在使用的时候注意其他的session的影响。
完