lsof 是否始终显示打开文件的已解析绝对路径名

lsof 是否始终显示打开文件的已解析绝对路径名

在 的输出中lsof,该列是否始终输出打开文件的已解析绝对路径名(在无符号链接或路径名NAME的意义上解析)?...

例如,如果我cd进入某个目录的符号链接,然后运行程序来打开该目录下的文件,是否lsof只显示该文件的解析绝对路径名?

我可以lsof输出已打开文件的未解析的绝对路径名(未解析的意思是目录符号链接应该出现在路径名中)吗?

谢谢。

答案1

如果没有选项,它应该以解析的形式提供路径名。从lsof(8) 手册:

打开的文件可以是常规文件、目录、块特殊文件、字符特殊文件、执行文本引用、库、流或网络文件(Internet 套接字、NFS 文件或 UNIX 域套接字)。可以通过路径选择文件或文件系统中的所有文件。

当然也可能有错误,比如路径名太长,在这种情况下,路径名不会被解析,但在其他方面lsof显然依赖于周围的包装函数readlink(),应该可以完成这项工作。

如果您确实指定了一个文件名,如lsof [options] [--] names,它应该被解析:

名称 这些是要列出的特定文件的路径名。符号链接在使用前已解析。可以使用“--”选项将名字与前面的选项分隔开。

当然,解析文件名的标准规则适用。符号链接级别太多会导致错误lsof依赖于 MAXSYMLINKS 变量 在 Linux 内核中硬编码至最大级别 40 个符号链接, 和对于变量未定义的其他系统 - 将其设置为 32

如果您指定-b选项,则不会解析文件名:

第三,如果 lsof 从系统挂载表获取的文件系统目录名称是符号链接,则 lsof 将无法解析这些链接。这是因为 -b 选项导致 lsof 避免使用它用来解析符号链接的内核 readlink(2) 函数。

答案2

我不知道正在使用的套接字文件是否应算作打开文件,但在 unix 域套接字的情况下,lsof只会列出NAME(并且只能通过)精确的套接字绑定的名称,无论是相对路径还是绝对路径,并且任何路径工件保持不变:

$ cd /tmp
$ nc -dUl ./././///sock &
[3] 6324
$ ls sock /tmp/sock ./sock
./sock  /tmp/sock  sock
$ lsof sock /tmp/sock ./sock
[nothing]
$ lsof ./././///sock
COMMAND  PID USER   FD   TYPE             DEVICE SIZE/OFF   NODE NAME
nc      6324  XXX    3u  unix 0xffff9f9faab76000      0t0 175260 ./././///sock type=STREAM

请注意,如果是非抽象的unix 域套接字,套接字绑定或连接到的路径仅在内核解析它之前才起作用;它是 [device,inode] 元组,它是套接字绑定或连接到的真实地址:

$ cd /tmp
$ nc -dUl ./././///sock &
[1] 7293
$ mv sock SOCK
$ lsof -aUp $!
COMMAND  PID  USER   FD   TYPE             DEVICE SIZE/OFF    NODE NAME
nc      7293   xxx    3u  unix 0xffff908d70bb5800      0t0 1137631 ./././///sock type=STREAM
$ lsof ./././///sock
lsof: status error on ./././///sock: No such file or directory
[stupid junk snipped]
$ lsof SOCK
[nothing]
$ nc -U ./././///sock
nc: unix connect failed: No such file or directory
$ nc -U SOCK
[connected ok]

lsof也无法找到与另一个套接字“连接”(即设置了默认发送地址)的数据报套接字,无法区分@名称中带有 a 的抽象套接字和名称中带有 NUL 字节的抽象套接字,等等。

以防万一有人想知道,所有需要的信息都可以通过界面获得sock_diagUDIAG_SHOW_VFSUDIAG_SHOW_PEER查看linux/unix_udiag.h标题);只是这lsof太愚蠢了,无法利用它。

注意:这些示例使用nc来自 Debian 的软件包netcat-openbsd,它支持 Unix 套接字。

相关内容