我一直想知道这一点,但从未花时间去弄清楚,所以我现在就这样做 - 用法的便携性如何此处显示或/proc/$$/fd/$N
或/dev/fd/$N
?我明白POSIX 保证 /dev/null, /dev/tty, and /dev/console
(尽管我直到前几天阅读评论后才发现这个答案)但其他人呢?
据我所知,它们非常常见,但是在哪些系统中我可以不是期望找到他们吗?为什么不?找到其中一个的可能性是否比找到另一个更大?他们总是表现出相似的属性吗?
我倾向于以各种方式广泛使用这些设备,我想知道我是否有可能在尝试中遇到困难。
另外,上述问题应该被理解为只是我的思考我想知道,但是,由于我显然必须首先询问,因此我可能在这方面不是最了解的,因此不应将它们视为对答案的严格要求。如果可以的话请告诉我。
答案1
这些符号链接在 Linux 上几乎是通用的,但它们在其他任何地方都不存在(除了模拟它们的 Cygwin 上)。也存在于 AIX 和 Solaris 上,但它们不是符号链接。可移植地,要获取有关打开文件的信息,请安装./proc/PID/fd/NUM
/proc/PID/fd/NUM
lsof
与/proc/PID/fd
Linux
在 Linux 下,是一个稍微神奇的符号链接,指向具有 ID 的进程的文件/proc/PID/fd/NUM
PID文件描述符已打开编号。这个链接很神奇,例如,即使文件被删除,它也可以用来访问该文件。该链接也将通过重命名来跟踪文件。/proc/self
是一个神奇的符号链接,指向哪里/proc/PID
PID是访问链接的进程。
几乎所有 Linux 系统都存在此功能。它是由驱动程序提供的进程文件系统,它在技术上是可选的,但用于很多事情(包括制作作品ps
- 它从中读取),即使在嵌入式系统上它也几乎从未被遗漏。/proc/PID
西格文
Cygwin 模拟 Linux (对于 Cygwin 进程)和./proc/PID/fd/NUM
/proc/self
索拉里斯(从2.6版本开始),艾克斯
每个文件描述符都有条目,但它们显示为与打开的文件相同的类型,因此它们不提供有关文件路径的信息。然而他们确实报告了相同的情况/proc/PID/fd
stat
信息为fstat
将向打开文件的进程报告,因此可以确定文件所在的文件系统及其索引节点号。目录显示为符号链接,但它们是只能跟随的魔术符号链接,并readlink
返回空字符串。
在 AIX 下,procfiles
命令显示有关进程打开的文件的一些信息。在 Solaris 下,pfiles
命令显示有关进程打开的文件的一些信息。这不包括文件的路径(在 Solaris 上,从 Solaris 10 开始包括,见下文)。
索拉里斯(自从版本 10)
除了 之外,现代 Solaris 版本还包含类似于 Linux 中的符号链接的符号链接。这/proc/PID/fd/NUM
/proc/PID/path/NUM
/proc/PID/fd/NUM
pfiles
命令显示有关进程的打开文件的信息,包括路径。
计划9
/proc/PID/fd
是一个文本文件,其中进程打开的每个文件描述符包含一条记录(行)。那里不跟踪文件名。
QNX
/proc/PID/
是一个目录,但它不包含任何有关文件描述符的信息。
Unices 可以/proc
但不能直接访问文件描述符
(注意:有时可以通过浏览可在 下访问的内存映像来获取有关进程打开文件的信息/proc
。我不认为这是“直接访问”。)
Unices文件在哪里/proc/PID
proc 文件系统本身开始在 UNIX 第 8 版中,但具有不同的结构,并经历了 Plan 9 并回到了一些 unice。我认为所有具有 PID 的操作系统/proc
都有一个对应于每个 PID 的条目,但在许多系统上,它是一个常规文件,而不是一个目录。以下系统有一个需要阅读的:/proc/PID
ioctl
迷你3
MINIX 3 有一个过程服务器它提供了几个类似 Linux 的组件,包括目录。然而没有。/proc/PID/
/proc/PID/fd
自由BSD
FreeBSD 有目录,但它们不提供有关打开文件描述符的信息。 (然而,有一个类似于 Linux 的,可以通过符号链接访问可执行文件。)/proc/PID/
/proc/PID/file
/proc/PID/exe
FreeBSD 的 procfs 是已弃用。
没有统一的/proc
- 惠普-UX
- 开放BSD
- 网络BSD
- Mac OS X
通过其他渠道获取文件描述符信息
定影器
这fuser
命令列出打开指定文件或在指定安装点上打开文件的进程。此命令是标准命令(适用于所有XSI- 兼容系统,即具有 X/Open 系统接口扩展的 POSIX)。
您无法使用此实用程序从进程名转到文件名。
洛夫
Lsof 代表“列出打开的文件”。它是一个第三方工具,适用于大多数 UNIX 变体(但通常不是默认安装的一部分)。获取有关打开文件的信息非常依赖于系统,因为上面的分析可能会让您产生怀疑。 lsof 维护者已经完成了将所有这些组合在一个界面下的工作。
您可以阅读常问问题看看lsof要忍受什么样的困难。在大多数 unice 上,获取有关打开文件名称的信息需要解析内核数据结构。引用 FAQ 3.3“为什么 lsof 不报告完整路径名?”:
Lsof 无法从以下方言的内核名称缓存中获取路径名称组件:
- 艾克斯
只有 Linux 内核在其维护的有关打开文件的结构中记录完整路径名;相反,大多数内核将路径名转换为设备和节点号双元组,并在文件打开后将它们用于后续文件引用。
如果您需要从lsof
的输出中解析信息,请务必使用-F
模式(每行一个字段),最好使用-F0
模式(空分隔字段)。要获取有关特定进程的特定文件描述符的信息,请使用-a
带有和 的选项,例如。-p PID
-d NUM
lsof -a -p 123 -d 0 -F0n
/dev/fd/NUM
用于当前进程的文件描述符
许多 UNIX 变体提供了一种方法让进程通过文件名访问其打开的文件:打开相当于调用/dev/fd/NUM
dup(NUM)
。当程序需要文件名但您想要传递已经打开的文件(例如管道或套接字)时,这些名称很有用;例如实现的 shell流程替代在可用的地方使用它们(在不可用的地方使用临时命名管道/dev/fd
)。
在存在的地方/dev/fd
,通常(总是?)同义词(有时是符号链接,有时是硬链接,有时是具有等效属性的魔术文件)/dev/stdin
= /dev/fd/0
,/dev/stdout
= /dev/fd/1
,/dev/stderr
= /dev/fd/2
。
答案2
实现方式/proc
及其提供的功能没有以任何方式标准化,例如这里。根据 Wikipedia,FreeBSD 正在“逐步淘汰” /proc
,请参阅此处了解详细信息。
截至/dev
,/dev/fd/
不是 POSIX 或单用户规范 (SUSv3) 的一部分,而 System V 和 BSD 支持它。
附录:
Linux:/dev/fd/*
是到/proc/self/fd
.
FreeBSD:/dev/fd/*
通过 fdescfs 提供。
NetBSD:与 FreeBSD 相同。
OpenBSD:与 FreeBSD 相同。
索拉里斯:有/dev/fd/*
。
IRIX:有/dev/fd/*
。
Tru64 Unix:有/dev/fd/*
根据nixdoc.net,HP 的正版 Tru64 文档令人费解(天哪,真是一团糟!你什么也没找到!)。
AIX:未从公开文档中找到任何迹象。
HP-UX:与 AIX 相同。