与维基百科相比,什么样的文件描述符描述更简单?为什么需要它们?比如说,以壳进程为例,它是如何应用的呢? 进程表是否包含多个文件描述符?如果是,为什么?
当前回答
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。
其他回答
In simple words, when you open a file, the operating system creates an entry to represent that file and store the information about that opened file. So if there are 100 files opened in your OS then there will be 100 entries in OS (somewhere in kernel). These entries are represented by integers like (...100, 101, 102....). This entry number is the file descriptor. So it is just an integer number that uniquely represents an opened file for the process. If your process opens 10 files then your Process table will have 10 entries for file descriptors.
类似地,当您打开一个网络套接字时,它也由一个整数表示,称为套接字描述符。 我希望你能理解。
文件描述符(FD):
In Linux/Unix, everything is a file. Regular file, Directories, and even Devices are files. Every File has an associated number called File Descriptor (FD). Your screen also has a File Descriptor. When a program is executed the output is sent to File Descriptor of the screen, and you see program output on your monitor. If the output is sent to File Descriptor of the printer, the program output would have been printed. Error Redirection : Whenever you execute a program/command at the terminal, 3 files are always open standard input standard output standard error. These files are always present whenever a program is run. As explained before a file descriptor, is associated with each of these files. File File Descriptor Standard Input STDIN 0 Standard Output STDOUT 1 Standard Error STDERR 2 For instance, while searching for files, one typically gets permission denied errors or some other kind of errors. These errors can be saved to a particular file. Example 1
$ ls mydir 2>错误文件.txt
标准错误的文件描述符是2。 如果没有任何名为mydir的目录,则命令的输出将保存到文件errorfile.txt 使用"2>"将错误输出重定向到名为"errorfile.txt"的文件 因此,程序输出不会充满错误。 我希望你得到了答案。
其他答案补充了很好的内容。我只是说说我的看法。
根据维基百科,我们可以肯定地知道:文件描述符是非负整数。我认为最重要的一点是:
文件描述符绑定到进程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 ]
任何操作系统都有正在运行的进程(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)。
推荐文章
- 如何使用查找命令从列表中查找所有具有扩展名的文件?
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- 在Bash中获取日期(比当前时间早一天)
- Linux: kill后台任务
- 在OSX中永久设置PATH环境变量
- Trap和中断的区别是什么?
- 如何在C程序中获取当前目录?
- 如何在Bash中逐行合并两个文件
- 如何从远程SSH会话发送数据到本地剪贴板
- 我如何得到bash完成工作与别名?
- SSH端口转发~/。ssh /配置文件?
- 如何将多个文件的内容追加到一个文件
- 如何进入每个目录并执行命令?
- Tar归档,从文件列表中获取输入
- 如何复制文件跨计算机使用SSH和MAC OS X终端