与维基百科相比,什么样的文件描述符描述更简单?为什么需要它们?比如说,以壳进程为例,它是如何应用的呢? 进程表是否包含多个文件描述符?如果是,为什么?
当前回答
As an addition to other answers, unix considers everything as a file system. Your keyboard is a file that is read only from the perspective of the kernel. The screen is a write only file. Similarly, folders, input-output devices etc are also considered to be files. Whenever a file is opened, say when the device drivers[for device files] requests an open(), or a process opens an user file the kernel allocates a file descriptor, an integer that specifies the access to that file such it being read only, write only etc. [for reference : https://en.wikipedia.org/wiki/Everything_is_a_file ]
其他回答
文件描述符只是任何开放资源的引用。只要您打开一个资源,内核就假定您将对其进行一些操作。所有通过程序和资源的通信都发生在一个接口上,这个接口由文件描述符提供。
由于一个进程可以打开多个资源,所以一个资源可能有多个文件描述符。 你可以通过简单地运行, Ls -li /proc/<pid>/fd/这里的pid是进程的进程id
其他答案补充了很好的内容。我只是说说我的看法。
根据维基百科,我们可以肯定地知道:文件描述符是非负整数。我认为最重要的一点是:
文件描述符绑定到进程ID。
我们知道最著名的文件描述符是0、1和2。 0对应STDIN, 1对应STDOUT, 2对应STDERR。
比如说,以壳进程为例,它是如何应用的呢?
检查这段代码
#>sleep 1000 &
[12] 14726
我们创建了一个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
第4列FD和下一列TYPE对应于文件描述符和文件描述符类型。
FD的一些值可以是:
cwd – Current Working Directory
txt – Text file
mem – Memory mapped file
mmap – Memory mapped device
但是真正的文件描述符在下面:
NUMBER – Represent the actual file descriptor.
数字后面的字符,即“1u”,表示文件打开的模式。R代表读,w代表写,u代表读和写。
TYPE文件类型。TYPEs的一些值是:
REG – Regular File
DIR – Directory
FIFO – First In First Out
但是所有的文件描述符都是 CHR—字符特殊文件(或字符设备文件)
现在,我们可以使用lsof -p PID轻松识别STDIN, STDOUT和STDERR的文件描述符,或者如果我们使用ls /proc/PID/fd.也可以看到同样的情况
还要注意,内核所跟踪的文件描述符表与文件表或inodes表并不相同。正如其他一些答案解释的那样,这些是独立的。
例如,您可能会问自己这些文件描述符的物理位置,以及在/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
/dev/pts/6纯粹存在于内存中。这些不是常规文件,而是所谓的字符设备文件。你可以用:ls -l /dev/pts/6检查,它们将以c开头,在我的例子中是crw—w----。
回想一下大多数Linux之类的操作系统定义了七种类型的文件:
常规文件 目录 字符设备文件 块设备文件 本地域套接字 命名管道(fifo)和 符号链接
As an addition to other answers, unix considers everything as a file system. Your keyboard is a file that is read only from the perspective of the kernel. The screen is a write only file. Similarly, folders, input-output devices etc are also considered to be files. Whenever a file is opened, say when the device drivers[for device files] requests an open(), or a process opens an user file the kernel allocates a file descriptor, an integer that specifies the access to that file such it being read only, write only etc. [for reference : https://en.wikipedia.org/wiki/Everything_is_a_file ]
这里提供的所有答案都很棒,这是我的版本
文件描述符是非负整数,充当“文件”或I/O资源(如管道、套接字或数据流)的抽象句柄。这些描述符帮助我们与这些I/O资源进行交互,并使使用它们变得非常容易。I/O系统对于用户进程来说是一个字节流(I/O流)。Unix进程使用描述符(小的无符号整数)来引用I/O流。与I/O操作相关的系统调用以一个描述符作为参数。
有效的文件描述符范围从0到可配置的最大描述符数(ulimit, /proc/sys/fs/file-max)。内核为FD表的std输入(0),std输出(1)和std错误(2)分配desc.。如果文件打开失败,fd返回-1。
当进程成功请求打开一个文件时,内核返回一个文件描述符,该描述符指向内核全局文件表中的一个条目。文件表项包含文件的inode、字节偏移量和该数据流的访问限制(只读、只写等)等信息。
A file descriptor is an opaque handle that is used in the interface between user and kernel space to identify file/socket resources. Therefore, when you use open() or socket() (system calls to interface to the kernel), you are given a file descriptor, which is an integer (it is actually an index into the processes u structure - but that is not important). Therefore, if you want to interface directly with the kernel, using system calls to read(), write(), close() etc. the handle you use is a file descriptor.
系统调用上覆盖了一个抽象层,即stdio接口。这比基本的系统调用提供了更多的功能/特性。对于这个接口,您获得的不透明句柄是一个FILE*,它由fopen()调用返回。有很多很多函数使用stdio接口fprintf(), fscanf(), fclose(),它们让你的生活更简单。在C语言中,stdin、stdout和stderr分别是FILE*,在UNIX中分别映射到文件描述符0、1和2。
推荐文章
- 如何从命令行通过mysql运行一个查询?
- 在创建守护进程时执行双fork的原因是什么?
- 对以制表符分隔的文件进行排序
- 如何使用查找命令从列表中查找所有具有扩展名的文件?
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- 在Bash中获取日期(比当前时间早一天)
- Linux: kill后台任务
- 在OSX中永久设置PATH环境变量
- Trap和中断的区别是什么?
- 如何在C程序中获取当前目录?
- 如何在Bash中逐行合并两个文件
- 如何从远程SSH会话发送数据到本地剪贴板
- 我如何得到bash完成工作与别名?
- SSH端口转发~/。ssh /配置文件?
- 如何将多个文件的内容追加到一个文件