Linux文件描述符详解


参考书籍:《Linux Shell核心编程指南》——丁明一

一、概念

文件描述符是一个非负整数,内核需要通过这个文件描述符才可以访问文件

文件描述符好比一本书的目录(索引),通过这个索引可以找到需要的内容

在Linux系统中内核默认为每个进程创建三个标准的文件描述符:分别是0(标准输入)、1(标准输出)、2(标准错误)。通过查看/proc/PID/fd目录下的文件,就可以查看每个进程拥有的所有文件描述符

例如:查看当前shell的文件描述符
在这里插入图片描述
255是一个小技巧,bash用于在重定向时保留这些副本.

当打开文件时,系统内核会为特定的进程自动创建对应的文件描述符
示例:使用vi打开一个文件
在这里插入图片描述
再开启第二个终端窗口,查看vi进程的进程号
在这里插入图片描述
查看文件描述符
在这里插入图片描述
vi进程除了拥有三个标准文件描述符外,还有一个4号文件描述符,该描述符索引/var/log/.messages.swp文件。vi程序默认将所有的修改都写入该文件,只有在vi中执行保存命令才会将数据同步到/var/log/messages。

1.1.特点

优点

1、基于文件描述符的I/O操作兼容POSIX标准。
2、在UNIX、Linux的系统调用中,大量的系统调用都是依赖于文件描述符。

缺点

1、在非UNIX/Linux操作系统上(如Windows NT),无法基于这一概念进行编程。
2、由于文件描述符在形式上不过是个整数,当代码量增大时,会使编程者难以分清哪些整数意味着数据,哪些意味着文件描述符。因此,完成的代码可读性也就会变得很差。

二、手动创建文件描述符

2.1.语法

2.1.1.创建

exec 文件描述符 <> 文件名

2.1.2.调用

&文件描述符

2.1.3.关闭

exec 文件描述符<&-或
exec 文件描述符>&-

2.2.重定向输出的文件描述符

touch test.txt
exec 12>test.txt	#创建仅可输出的文件描述符

在这里插入图片描述
接下来就可以通过文件描述符去操作文件

echo hello >&12
echo world >&12
cat test.txt

在这里插入图片描述

cat <&12	#不支持输入

在这里插入图片描述

exec 12<&-		#关闭输出文件描述符
echo bob >&12	#关闭后无法再使用该描述符

在这里插入图片描述

2.3.重定向输入的文件描述符

exec 13<test.txt
cat <&13		#注意,文件仅可以被读取一次

在这里插入图片描述
在这里插入图片描述

exec 13<&-		#关闭输入文件描述符

2.4.既可以输出又可以输入的文件描述符

exec 14<>test.txt
cat <&14
echo bob >&14
cat test.txt

在这里插入图片描述

exec 14<&-

三、使用read命令读取文件描述符

echo 'line1
> line2
> line3' > new.txt
exec 12<new.txt
read -u12 content	#读取一行的值并赋值给content
[root@localhost tmp]# echo $content
line1

read -u12 content	#再读取一行
[root@localhost tmp]# echo $content
line2

read -u12 content	#读取最后一行
[root@localhost tmp]# echo $content
line3

cat <&12	#cat也无法读取任何内容

在这里插入图片描述

exec 12<&-

从上面的实验可以看出,文件描述符不是简单地对应一个文件的,还包含很多文件相关的信息,如权限、文件偏移量等。

文件偏移量更像一个指针,默认该指针指向的是文件的起始位置,当使用read命令读取一行数据后,该指针会指向下一行数据,再使用read读取一行数据,指针再往下移动一行,依次类推,直到文件结束。
如图:
在这里插入图片描述
而使用cat命令会读取文件的全部内容,文件描述符的指针会一次性跳到文件的末尾。

read命令还可以通过-n选项指定读取任意字符的数据

exec 12<new.txt
read -u12 -n1 content
[root@localhost tmp]# echo $content
l
read -u12 -n1 content
[root@localhost tmp]# echo $content
i

不仅查看内容会导致指针移动,写入数据也会导致指针移动。
创建文件描述符时,如果文件描述符对应的文件不存在,系统会自动创建一个新的空文件。

exec 12<>file.txt
echo Linux >&12
echo windows >&12
cat <&12	#通过文件描述符查看为空
cat file.txt	#查看文件内容正常

在这里插入图片描述
exec 12<&-

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页