/dev/fd/3 有一些特别之处

qqw*_*qqw 10 ls file-descriptors

我一直在尝试了解文件描述符。当我输入“ls -l /dev/fd/”时,我得到

lrwx------ 1 me users 64 May  2 16:02 0 -> /dev/pts/5
l-wx------ 1 me users 64 May  2 16:02 1 -> /home/me/file
lrwx------ 1 me users 64 May  2 16:02 2 -> /dev/pts/5
lr-x------ 1 me users 64 May  2 16:02 3 -> /proc/31518/fd
Run Code Online (Sandbox Code Playgroud)

/dev/fd/3 似乎指向当前进程。但是,我见过的文件描述符的解释,例如 http://www.tldp.org/LDP/abs/html/io-redirection.html,不要说 /dev/fd/3 有什么特别之处(和暗示它就像 N > 3 的任何 /dev/fd/N 一样)。这里发生了什么?

我已经在 arch linux 和 ubuntu 上观察到了这一点,但没有在我有 ssh 帐户的 solaris 服务器上观察到。

gol*_*cks 15

/dev/fd/3 似乎指向当前进程。

即,ls它本身(注意 pid 之后将不存在)。所有这些实际上都与当前进程有关,因为文件描述符不是全局的;整个系统不仅仅只有一个 0、1 和 2——每个进程都有一个单独的 0、1 和 2。

正如 Frederik Dweerdt 所说,/dev/fd是一个符号链接。如果您ls从不同的终端重复您的操作,您会注意到指向不同 pty 的链接。这些将匹配tty命令的输出。

ls示例中,我认为描述符 3 是用于读取文件系统的描述符。一些open()支持文件描述符生成的C 命令(例如,)保证返回“最低编号的未使用文件描述符”POSIX——注意低级 open() 实际上不是标准 C 的一部分)。所以它们在关闭后会被回收(如果你反复打开和关闭不同的文件,你会一遍又一遍地得到 3 作为 fd)。

如果你想知道它们是如何存在的,这里有一段 C 代码 using opendir(),你可能会在 ls 的源代码中找到它:

// open directory for reading
DIR *dh = opendir(".");
// print the fd of the directory handle to standard out:
printf("fd: %d\n", dirfd(dh));
closedir(dh);  
Run Code Online (Sandbox Code Playgroud)

按原样运行,fd 将为 3,因为这是最低的未使用描述符(0、1 和 2 已存在)。


Hau*_*ing 14

/dev/fd/3不是标准描述符(编辑:赋值)。它(编辑:超过 0、1 和 2)特定于您的情况(ls)。您可以通过 strace 运行 ls 以了解会发生什么:

strace -e trace=openat,readlink ls -l /dev/fd/
openat(AT_FDCWD, "/dev/fd/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
readlink("/dev/fd/0", "/dev/pts/0", 65) = 10
readlink("/dev/fd/1", "/dev/pts/0", 65) = 10
readlink("/dev/fd/2", "/dev/pts/0", 65) = 10
readlink("/dev/fd/3", "/proc/28401/fd", 65) = 14
Run Code Online (Sandbox Code Playgroud)

ls就是显示里面的内容/dev/fd是一样的/proc/self/fdls必须打开目录才能读取其条目。/dev/fd/3只是这个目录的文件描述符。

其他程序没有/dev/fd/3

start cmd:> sleep 100 &
[1] 28414

ec:0   17:28:10  hl@inno:~/.wine/drive_c
start cmd:> ls -l /proc/28414/fd
insgesamt 0
crw------- 1 hl tty 136, 0 18. Apr 01:18 0
crw------- 1 hl tty 136, 0 18. Apr 01:18 1
crw------- 1 hl tty 136, 0 18. Apr 01:18 2
Run Code Online (Sandbox Code Playgroud)


Fre*_*rdt 6

在 Archlinux 上,/dev/fd是指向/proc/self/fd. 你看到的是fd你的ls命令的目录。并且此命令确实将目录打开为文件描述符 3。

编辑:顺便说一句,了解正在发生的事情的一个好方法是使用strace. 您将看到打开文件描述符的进程。