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

mik*_*erv 23 process file-descriptors open-files proc portability

我一直想知道这一点,但从来没有花时间去了解,所以我现在就这样做 -此处显示/proc/$$/fd/$N或的用法有多便携/dev/fd/$N?我理解POSIX 保证 /dev/null, /dev/tty, and /dev/console (尽管我前几天在阅读了这个答案的评论后才发现这一点但是其他的呢?

据我所知,它们很常见,但我不能指望在哪些系统中找到它们?为什么不?找到一个比另一个更有可能吗?他们会总是表现出类似的属性吗?

我倾向于以各种方式广泛使用这些设备,我想知道是否有机会尝试一下。

此外,上述问题应该被理解为只是我我想知道的,但是,因为我显然首先要问,所以我在这方面可能不是最了解的,它们不应该被视为严格的要求一个答案。如果可以,请告诉我。

Gil*_*il' 29

该符号链接是准普遍在Linux上,但它们不存在其他任何地方(除了在Cygwin看齐它们)。也存在于 AIX 和 Solaris 上,但它们不是符号链接。可移植地,要获取有关打开文件的信息,请安装./proc/PID/fd/NUM/proc/PID/fd/NUMlsof

/proc/PID/fd

Linux

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

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

赛格温

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

Solaris(从 2.6 版开始)、AIX

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

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

Solaris(从版本 10 开始

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

计划9

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

QNX

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

具有/proc但不能直接访问文件描述符的unices

(注意:有时可以通过翻阅可在/proc.

unices文件在哪里/proc/PID

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

  • 高达2.5 的Solaris
  • OSF/1 现在称为Tru64
  • 爱丽丝 (?)
  • 上海合作组织(?)

MINIX 3

MINIX 3 有一个procfs 服务器,它提供了几个类似 Linux 的组件,包括目录。然而没有。/proc/PID//proc/PID/fd

FreeBSD

FreeBSD 有目录,但它们不提供有关打开文件描述符的信息。(然而,它类似于 Linux 的,可以通过符号链接访问可执行文件。)/proc/PID//proc/PID/file/proc/PID/exe

FreeBSD 的 procfs 已弃用

/proc

  • 用户体验
  • 开放式BSD
  • NetBSD
  • 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)/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(IRIXOpenBSDNetBSD、 SCO、Solaris等)下, 中的条目/dev/fd是字符设备。无论文件描述符是否打开,它们通常都会出现,并且对于超过一定数量的文件描述符,条目可能不可用。
  • 在 FreeBSD 和 OSX 下,fdescfs文件系统提供了一个动态/dev/fd目录,它跟随着调用进程的打开描述符。/dev/fd如果/dev/fd未安装,则静态可用。
  • 在 OSF/1 (Tru64) 下,/dev/fd通过fdfs提供。
  • 有没有/dev/fd在AIX或HP-UX。


cou*_*ode 10

/proc实现的方式和它提供的功能没有以任何方式标准化,例如参见这里。根据维基百科,FreeBSD 正在“逐步淘汰” /proc详情请参见此处

截至/dev,/dev/fd/不是 POSIX 或单用户规范 (SUSv3) 的一部分,而 System V 和 BSD 支持它。

附录:

Linux:/dev/fd/*是指向/proc/self/fd.

FreeBSD:/dev/fd/*通过 fdescfs 提供。

NetBSD:与 FreeBSD 相同。

OpenBSD:与 FreeBSD 相同。

Solaris:有/dev/fd/*.

IRIX:有/dev/fd/*

Tru64 Unix:/dev/fd/*根据nixdoc.net,HP 的正版 Tru64 文档是高深莫测的(男孩,真是一团糟!你什么也没找到!)。

AIX:未从公开可用的文档中找到任何指示。

HP-UX:与 AIX 相同。