Nis*_*ant 351 unix operating-system file-descriptor
与维基百科相比,文件描述符的简化描述是什么?他们为什么需要?比如说,以shell进程为例,它是如何应用的?
进程表是否包含多个文件描述符.如果是,为什么?
Tay*_*yab 517
简单来说,当您打开文件时,操作系统会创建一个表示该文件的条目并存储有关该打开文件的信息.因此,如果您的操作系统中打开了100个文件,那么OS中将有100个条目(内核中的某个位置).这些条目由整数表示,如(... 100,101,102 ....).此条目号是文件描述符.因此它只是一个整数,它唯一地表示操作系统中打开的文件.如果您的进程打开10个文件,那么您的Process表将有10个文件描述符条目.
类似地,当您打开网络套接字时,它也由一个整数表示,它被称为套接字描述符.我希望你明白.
Bea*_*ano 106
文件描述符是一个不透明的句柄,用于用户和内核空间之间的接口,以识别文件/套接字资源.因此,当您使用open()
或socket()
(系统调用内核接口)时,会给您一个文件描述符,它是一个整数(它实际上是进程u结构的索引 - 但这并不重要).因此,如果您想直接与内核接口,使用系统调用read()
,write()
,close()
等你用手柄的文件描述符.
系统调用上覆盖了一层抽象,即stdio
接口.这提供了比基本系统调用更多的功能/特性.对于此接口,您获得的opaque句柄是a FILE*
,由fopen()
调用返回.有许多许多功能使用stdio
界面fprintf()
,fscanf()
,fclose()
,这是那里让您的生活更轻松.在C中,stdin
,stdout
,和stderr
是FILE*
,这在UNIX分别映射到文件描述符0
,1
和2
.
She*_*mar 93
从马的嘴里听到它:APUE(理查德史蒂文斯).
对于内核,文件描述符引用所有打开的文件.文件描述符是非负数.
当我们打开现有文件或创建新文件时,内核会向进程返回文件描述符. 内核维护一个正在使用的所有打开文件描述符的表.文件描述符的分配通常是顺序的,它们作为免费文件描述符池中的下一个空闲文件描述符分配给文件.当我们关闭文件时,文件描述符被释放并可用于进一步分配.
有关详细信息,请参见此图片:
当我们想要读取或写入文件时,我们使用open()或create()函数调用返回的文件描述符来标识文件,并将其用作read()或write()的参数.
按照惯例,UNIX系统shell将文件描述符0与进程的标准输入,文件描述符1与标准输出和文件描述符2与标准错误相关联.
文件描述符的范围从0到OPEN_MAX.
有关更多信息,请阅读APUE Book的第3章.
pro*_*sti 21
其他答案增加了很多东西.我只会加2美分.
根据维基百科我们肯定知道:文件描述符是一个非负整数.我认为最重要的缺失就是:
文件描述符绑定到进程ID.
我们知道大多数着名的文件描述符是0,1和2. 0对应于STDIN
,1对STDOUT
和2对STDERR
.
比如说,以shell进程为例,它是如何应用的?
看看这段代码
#>sleep 1000 &
[12] 14726
Run Code Online (Sandbox Code Playgroud)
我们创建了一个id为14726(PID)的进程.使用lsof -p 14726
我们可以得到这样的事情:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sleep 14726 root cwd DIR 8,1 4096 1201140 /home/x
sleep 14726 root rtd DIR 8,1 4096 2 /
sleep 14726 root txt REG 8,1 35000 786587 /bin/sleep
sleep 14726 root mem REG 8,1 11864720 1186503 /usr/lib/locale/locale-archive
sleep 14726 root mem REG 8,1 2030544 137184 /lib/x86_64-linux-gnu/libc-2.27.so
sleep 14726 root mem REG 8,1 170960 137156 /lib/x86_64-linux-gnu/ld-2.27.so
sleep 14726 root 0u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 1u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 2u CHR 136,6 0t0 9 /dev/pts/6
Run Code Online (Sandbox Code Playgroud)
第4列FD和下一列TYPE对应于文件描述符和文件描述符类型.
FD的一些值可以是:
cwd – Current Working Directory
txt – Text file
mem – Memory mapped file
mmap – Memory mapped device
Run Code Online (Sandbox Code Playgroud)
但真正的文件描述符在:
NUMBER – Represent the actual file descriptor.
Run Code Online (Sandbox Code Playgroud)
数字后面的字符即"1u"表示文件打开的模式.r用于读取,w用于写入,u用于读取和写入.
TYPE指定文件的类型.TYPE的一些值是:
REG – Regular File
DIR – Directory
FIFO – First In First Out
Run Code Online (Sandbox Code Playgroud)
但所有文件描述符都是CHR - 字符特殊文件(或字符设备文件)
现在,我们可以识别文件描述符STDIN
,STDOUT
并且STDERR
很容易lsof -p PID
,或者我们可以看到相同的文件描述符ls /proc/PID/fd
.
另请注意,内核跟踪的文件描述符表与files表或inode表不同.正如其他一些答案所解释的那样,这些是分开
你可能会问自己在哪里,这些文件描述符身体,什么是存储在/dev/pts/6
例如
sleep 14726 root 0u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 1u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 2u CHR 136,6 0t0 9 /dev/pts/6
Run Code Online (Sandbox Code Playgroud)
好吧,/dev/pts/6
纯粹生活在记忆中.这些不是常规文件,而是所谓的字符设备文件.您可以通过以下方式进行检查:在我的情况下ls -l /dev/pts/6
,它们将从一开始.c
crw--w----
回想起大多数Linux操作系统定义七种类型的文件:
小智 17
更多关于File Descriptor
:
File Descriptors
(FD)是(0, 1, 2, ...)
与打开的文件关联的非负整数.
0, 1, 2
是标准的FD的对应STDIN_FILENO
,STDOUT_FILENO
和STDERR_FILENO
(在定义的unistd.h
默认代表壳的打开程序启动时).
FD按顺序分配,意味着可能的最低未分配整数值.
可以在/proc/$pid/fd
(基于Unix的系统上)看到特定过程的FD .
Bal*_*alu 15
作为其他答案的补充,unix将所有内容都视为文件系统.键盘是一个只从内核角度读取的文件.该屏幕是只写文件.类似地,文件夹,输入输出设备等也被认为是文件.每当打开文件时,例如当设备驱动程序[用于设备文件]请求open(),或者进程打开用户文件时,内核就会分配一个文件描述符,这是一个整数,指定对该文件的访问权限,使其只读,只写等[供参考:https://en.wikipedia.org/wiki/Everything_is_a_file ]
Har*_*thi 13
提供的所有答案都很棒,这是我的版本——
\n文件描述符是非负整数,充当 \xe2\x80\x9cFiles\xe2\x80\x9d 或 I/O 资源(如管道、套接字或数据流)的抽象句柄。这些描述符帮助我们与这些 I/O 资源进行交互,并使使用它们变得非常容易。I/O 系统对于用户进程来说是可见的,作为字节流(I/O 流)。Unix 进程使用描述符(小的无符号整数)来引用 I/O 流。与 I/O 操作相关的系统调用以描述符作为参数。
\n有效文件描述符的范围从 0 到可配置的最大描述符编号(ulimit、/proc/sys/fs/file-max)。内核分配 desc。对于 FD 表的标准输入 (0)、标准输出 (1) 和标准错误 (2)。如果文件打开不成功,fd 返回-1。
当进程成功请求打开文件时,内核返回一个文件描述符,该描述符指向内核全局文件表中的条目。文件表条目包含文件的索引节点、字节偏移量以及该数据流的访问限制(只读、只写等)等信息。
\n小智 12
文件描述符(FD):
$ ls mydir 2> errorsfile.txt
标准错误的文件描述符为2。
如果没有名为mydir的目录,则命令的输出将保存到文件errorfile.txt中。
使用“ 2>”将错误输出重定向到名为“ errorfile”的文件。 txt”,
因此程序输出不会出现错误。
我希望你能得到答案。
文件描述符只不过是任何开放资源的引用。一旦您打开一个资源,内核就会假设您将对其进行一些操作。通过程序和资源进行的所有通信都通过接口进行,并且该接口由文件描述符提供。
由于一个进程可以打开多个资源,因此一个资源可能具有多个文件描述符。
您只需运行即可查看链接到该进程的所有文件描述符,
ls -li /proc/<pid>/fd/
这里 pid 是您的进程的进程 ID
小智 5
任何操作系统都有进程(p)在运行,比如p1、p2、p3等等。每个进程通常都会持续使用文件。
每个进程都由一个进程树(或一个进程表,用另一种说法)组成。
通常,操作系统表示在各个工序中的每个文件由一个数字(即,在每个过程树/表)。
进程中使用的第一个文件是file0,第二个是file1,第三个是file2,依此类推。
任何这样的数字都是一个文件描述符。
文件描述符通常是整数(0、1、2 而不是 0.5、1.5、2.5)。
鉴于我们经常将进程描述为“进程表”,并且鉴于表中有行(条目),我们可以说每个条目中的文件描述符单元用于表示整个条目。
类似地,当你打开一个网络套接字时,它有一个套接字描述符。
在某些操作系统中,您可能会耗尽文件描述符,但这种情况极为罕见,普通计算机用户不必为此担心。
文件描述符可能是全局的(进程 A 以 0 开始,以 1 结束;进程 B 以 2 开始,以 3 结束)等等,但据我所知,通常在现代操作系统中,文件描述符不是全局的,实际上是特定于进程的(进程 A 从 0 开始,以 5 结束,而进程 B 从 0 开始,以 10 结束)。
小智 5
除了上述所有简化的响应之外。
如果您在 bash 脚本中处理文件,最好使用文件描述符。
例如:如果要读取和写入文件“test.txt”,请使用如下所示的文件描述符:
FILE=$1 # give the name of file in the command line
exec 5<>$FILE # '5' here act as the file descriptor
# Reading from the file line by line using file descriptor
while read LINE; do
echo "$LINE"
done <&5
# Writing to the file using descriptor
echo "Adding the date: `date`" >&5
exec 5<&- # Closing a file descriptor
Run Code Online (Sandbox Code Playgroud)