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


20

我一直想知道这一点,但从来没有花时间找出来,所以我现在就这样做-是使用便携式怎么这里显示的任一/proc/$$/fd/$N/dev/fd/$N?我了解POSIX担保 /dev/null, /dev/tty, and /dev/console (尽管我是在阅读有关此答案的评论后的第二天才发现的),但是其他这些担保呢?

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

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

另外,上述问题应该被理解为仅是我,我想知道,但是,因为我显然要问的第一个地方,我可能不知道最好在这方面,他们不应该被认为是严格要求答案。请告诉我,如果可以的话。

Answers:


27

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

Unices与 /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

每个文件描述符都有一些条目,但是它们的显示形式与打开的文件相同,因此它们不提供有关文件路径的信息。但是,它们确实报告的信息与向打开文件的进程报告的信息相同,因此可以确定文件位于哪个文件系统上以及其索引节点号。目录显示为符号链接,但是它们是魔术符号链接,只能跟随它们,并返回空字符串。/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 8版,但结构不同,经过了Plan 9并回到了一些unices。我认为所有带有的/procPID的每个操作系统都有一个条目,但是在许多系统上,这是一个常规文件,而不是目录。以下系统具有,需要与一起阅读:/proc/PIDioctl

  • Solaris最高2.5
  • OSF / 1现在称为Tru64
  • IRIX(?)
  • 上合组织(?)

MINIX 3

MINIX 3有一个procfs服务器,它提供了几个类似Linux的组件,包括目录。但是,这不存在。/proc/PID//proc/PID/fd

FreeBSD

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

FreeBSD的procfs已弃用

没有的Unices /proc

  • HP-UX
  • OpenBSD的
  • NetBSD
  • Mac OS X

通过其他渠道的文件描述符信息

定影器

fuser命令列出了打开了指定文件或在指定安装点上打开了文件的进程。此命令是标准命令(在所有符合XSI的系统上可用,即具有X / Open System Interface Extension的POSIX)。

您无法使用此实用程序将进程从文件名转到文件名。

索夫

Lsof代表“列出打开的文件”。它是大多数unix变体可用的第三方工具(但通常不是默认安装的一部分)。获取有关打开文件的信息非常依赖于系统,因为上面的分析可能使您感到怀疑。lsof维护者已经完成了在单个界面下将所有内容组合在一起的工作。

您可以阅读FAQ来了解lsof必须解决哪些困难。在大多数Unice上,获取有关打开文件名的信息需要解析内核数据结构。引用于常见问题3.3:“ lsof为什么不报告完整路径名?”:

Lsof无法从以下方言的内核名称缓存中获取路径名称组件:

  • 艾克斯

只有Linux内核在它维护的有关打开文件的结构中记录完整的路径名。取而代之的是,大多数内核在打开文件后将路径名转换为设备和节点号的双精度位,并将其用于后续文件引用。

如果您需要从lsof的输出中解析信息,请确保使用-F模式(每行一个字段),最好使用-F0模式(以空分隔的字段)。要获取有关特定进程的特定文件描述符的信息,请使用-a带有和的选项,例如。-p PID-d NUMlsof -a -p 123 -d 0 -F0n

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

许多unix变体为进程提供了一种通过文件名访问其打开文件的方法:open 相当于调用。当程序需要文件名但要传递已经打开的文件(例如管道或套接字)时,这些名称很有用;例如,实现进程替换的外壳将在可用的地方使用它们(使用不可用的临时命名管道)。/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。

您关于Solaris的陈述有些过时了。对于不到10年的Solaris发行版,该pfiles命令显示文件描述符路径。它从/proc/<pid>/path您可能还会提到的目录中检索此信息。请参阅docs.oracle.com/cd/E19253-01/817-0547/esxiq/index.html
jlliagre 2014年

9

该方法/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相同。

Solaris:具有/dev/fd/*

IRIX:具有/dev/fd/*

Tru64 Unix:/dev/fd/*根据nixdoc.net的资料,HP上的真正Tru64文档是难以理解的(男孩,真是一团糟!您什么都找不到!)。

AIX:从公开文档中找不到任何指示。

HP-UX:与AIX相同。


所以我会/dev/fd/1在BSD上找到一个链接到我当前文件的文件1>?我通常在linux中做的一件事echo 'command' | . /dev/fd/0-是这样吗?
mikeserv

我现在无法访问BSD系统,但这就是我的理解。
countermode

1
我想,如果您发现时间只是在此基础上扩展一点,我会接受这个答案,除非有任何令人惊讶的教授职位。无论如何,与之链接的第一篇文章都是很有启发性的阅读-非常感谢。
mikeserv 2014年

是的 我想fd教授毕竟出现了,是吗?那么,下次好运吗?
mikeserv

1
那好吧。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相同。
countermode
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.