文件描述符链接的可移植性

文件描述符链接的可移植性

我一直想知道这一点,但从未花时间去弄清楚,所以我现在就这样做 - 用法的便携性如何此处显示/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/NUMlsof

/proc/PID/fd

Linux

在 Linux 下,是一个稍微神奇的符号链接,指向具有 ID 的进程的文件/proc/PID/fd/NUMPID文件描述符已打开编号。这个链接很神奇,例如,即使文件被删除,它也可以用来访问该文件。该链接也将通过重命名来跟踪文件。/proc/self是一个神奇的符号链接,指向哪里/proc/PIDPID是访问链接的进程。

几乎所有 Linux 系统都存在此功能。它是由驱动程序提供的进程文件系统,它在技术上是可选的,但用于很多事情(包括制作作品ps- 它从中读取),即使在嵌入式系统上它也几乎从未被遗漏。/proc/PID

西格文

Cygwin 模拟 Linux (对于 Cygwin 进程)和./proc/PID/fd/NUM/proc/self

索拉里斯(从2.6版本开始),艾克斯

每个文件描述符都有条目,但它们显示为与打开的文件相同的类型,因此它们不提供有关文件路径的信息。然而他们确实报告了相同的情况/proc/PID/fdstat信息为fstat将向打开文件的进程报告,因此可以确定文件所在的文件系统及其索引节点号。目录显示为符号链接,但它们是只能跟随的魔术符号链接,并readlink返回空字符串。

在 AIX 下,procfiles命令显示有关进程打开的文件的一些信息。在 Solaris 下,pfiles命令显示有关进程打开的文件的一些信息。这不包括文件的路径(在 Solaris 上,从 Solaris 10 开始包括,见下文)。

索拉里斯(自从版本 10

除了 之外,现代 Solaris 版本还包含类似于 Linux 中的符号链接的符号链接。这/proc/PID/fd/NUM/proc/PID/path/NUM/proc/PID/fd/NUMpfiles命令显示有关进程的打开文件的信息,包括路径。

计划9

/proc/PID/fd是一个文本文件,其中进程打开的每个文件描述符包含一条记录(行)。那里不跟踪文件名。

QNX

/proc/PID/是一个目录,但它不包含任何有关文件描述符的信息。

Unices 可以/proc但不能直接访问文件描述符

(注意:有时可以通过浏览可在 下访问的内存映像来获取有关进程打开文件的信息/proc。我不认为这是“直接访问”。)

Unices文件在哪里/proc/PID

proc 文件系统本身开始在 UNIX 第 8 版中,但具有不同的结构,并经历了 Plan 9 并回到了一些 unice。我认为所有具有 PID 的操作系统/proc都有一个对应于每个 PID 的条目,但在许多系统上,它是一个常规文件,而不是一个目录。以下系统有一个需要阅读的:/proc/PIDioctl

  • Solaris 高达2.5
  • OSF/1 现在称为特鲁64
  • 伊瑞克斯(?)
  • 上合组织(?)

迷你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 NUMlsof -a -p 123 -d 0 -F0n

/dev/fd/NUM用于当前进程的文件描述符

许多 UNIX 变体提供了一种方法让进程通过文件名访问其打开的文件:打开相当于调用/dev/fd/NUMdup(NUM)。当程序需要文件名但您想要传递已经打开的文件(例如管道或套接字)时,这些名称很有用;例如实现的 shell流程替代在可用的地方使用它们(在不可用的地方使用临时命名管道/dev/fd)。

在存在的地方/dev/fd,通常(总是?)同义词(有时是符号链接,有时是硬链接,有时是具有等效属性的魔术文件)/dev/stdin= /dev/fd/0/dev/stdout= /dev/fd/1/dev/stderr= /dev/fd/2

  • 在 Linux 下,/dev/fd是到 的符号链接/proc/self/fd
  • 在大多数unices下(IRIX,开放BSD,网络BSD, 上合组织,索拉里斯, …), 中的条目/dev/fd是字符设备。无论文件描述符是否打开,它们通常都会出现,并且对于超过一定数量的文件描述符,条目可能不可用。
  • 在 FreeBSD 和 OSX 下,fdescfs文件系统提供了一个动态/dev/fd目录,该目录遵循调用进程的打开描述符。如果未安装,则静态/dev/fd可用。/dev/fd
  • 在 OSF/1 (Tru64) 下,/dev/fd通过提供FDFS
  • /dev/fdAIX 或 HP-UX 上没有。

答案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 相同。

相关内容