命令行手册

Man » lsof 手册在线 - lsof 手册页的详细在线文档

🌍
lsof - 列出打开的文件

概要

lsof [ -?abChHlnNOPQRtUvVX ] [ -A A ] [ -c c ] [ +c c ] [ +|-d d ] [ +|-D D ] [ +|-e s ] [ +|-E ]
[  +|-f  [cfgGn]  ]  [ -F [f] ] [ -g [s] ] [ -i [i] ] [ -k k ] [ -K k ] [ +|-L [l] ] [ +|-m m ] [
+|-M ] [ -o [o] ] [ -p s ] [ +|-r [t[m<fmt>]] ] [ -s [p:s] ] [ -S [t] ] [ -T [t] ] [  -u  s  ]  [
+|-w ] [ -x [fl] ] [ -z [z] ] [ -Z [Z] ] [ -- ] [names]

描述

Lsof 版本 4.99.4 会将其标准输出上的文件信息列出,这些信息是为以下 UNIX 变体打开的文件:

Apple Darwin 9、Mac OS X 10、macOS 11 及更高版本
FreeBSD 8.2 及更高版本
Linux 2.1.72 及更高版本
NetBSD 1.2 及更高版本
OpenBSD 7.2 及更高版本
Solaris 9、10 和 11 及更高版本
OpenIndiana 5.11 及更高版本

(有关如何获取最新 lsof 版本的信息,请参见此手册页的“DISTRIBUTION”部分。)

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

除了格式化的显示之外,lsof 还会生成可以由其他程序解析的输出。有关更多信息,请参见 -F 选项描述以及“其他程序的输出”部分。

除了生成单个输出列表之外,lsof 还会以重复模式运行。在重复模式下,它会生成输出、延迟,然后重复输出操作,直到通过中断或退出信号停止。有关更多信息,请参见 +|-r [t[m<fmt>]] 选项描述。

选项

如果没有指定任何选项,lsof 会列出所有活动进程拥有的所有打开的文件。

如果指定了任何列表请求选项,则必须明确请求其他列表请求,例如,如果指定了 -U 选项以列出 UNIX 套接字文件,除非也指定了 -N 选项,否则不会列出 NFS 文件;或者,如果使用 -u 选项指定了用户列表,则除非也指定了 -U 选项,否则不会列出属于列表中未包含的用户的 UNIX 域套接字文件。

通常,明确说明的列表选项是 ORed(即,指定 -i 选项而没有地址,以及 -ufoo 选项会生成一个列表,其中包含所有网络文件或属于由用户“foo”拥有的进程的文件)。例外情况是:

1 使用 -u 选项指定的“^”(否定)登录名或用户 ID (UID);

2 使用 -p 选项指定的“^”(否定)进程 ID (PID);

3 使用 -g 选项指定的“^”(否定)进程组 ID (PGID)。

4 对于使用 `-c` 选项指定的 `^`(否定)命令;

5 对于使用 `-s [p:s]` 选项指定(`^`)否定后的 TCP 或 UDP 协议状态名称。

由于它们表示排除,因此它们在应用任何其他选择标准之前,无需进行 OR 或 AND 运算,即可直接应用。

`-a` 选项可用于将选择进行 AND 运算。例如,指定 `-a`、`-U` 和 `-ufoo` 会生成仅包含属于用户 `foo` 的 UNIX 套接字文件的列表。

警告:`-a` 选项会导致所有列表选择选项都进行 AND 运算;即使将它放置在选项之间在语法上是可以接受的,也不能将其用于对选定的选项对进行 AND 运算。无论 `-a` 放置在哪里,它都会导致所有选择选项进行 AND 运算。

同一选择集中的项目——命令名称、文件描述符、网络地址、进程标识符、用户标识符、区域名称、安全上下文——组合成一个单独的 ORed 集合,并在结果参与 AND 运算之前应用。因此,例如,指定 -_, -_, -a 和 -ufff,ggg 将选择属于登录 fffggg 且具有与主机 aaa.bbb 或 ccc.ddd 建立网络连接的文件列表。

选项可以组合在一组前缀之后——例如,选项集 '-a -b -C' 可以表示为 -abC。但是,由于以下选项后面可以有值:+|-f-F-g-i+|-L-o+|-r-s-S-T-x-z,因此,当这些选项没有值时,请小心,以确保后面的字符不会产生歧义。例如,-Fn 可能表示 -F-n 选项,或者可能表示 -F 选项后面的字段标识符字符 n。当可能存在歧义时,请使用 '-' 字符开始新的选项——例如,'-F -n'。如果下一个选项是文件名,请在可能产生歧义的选项后跟 '-'——例如,'-F -- name'

^ +''-' 前缀都可以应用于一组选项。对于那些对于每个前缀都不具有不同含义的选项——例如,-i——可以将它们组合在任一前缀下。因此,例如,'+M -i' 可以表示为 '+Mi',并且该组的含义与单独的选项相同。当组中有一个或多个选项在不同的前缀下具有不同的含义时,请小心使用前缀分组——例如,+|-M'-iM''-i +M' 的请求不同。如果不确定,请使用带有适当前缀的单独选项。

`-? -h` 这两个等效选项选择用法(帮助)输出列表。当 `lsof` 检测到所提供的选项中存在错误时,它会显示此输出的缩短形式,并在显示解释每个错误的消息之后。 (根据您的 shell 要求,转义 `?` 字符。)

`-a` 导致列表选择选项进行 AND 运算,如上所述。

`-A A` 仅在配置为 AFS 且其 AFS 内核代码通过动态模块实现的系统上可用。它允许 `lsof` 用户指定 `A` 作为备用名称列表文件,内核可以在其中找到动态模块的地址。有关动态模块、它们的符号以及它们如何影响 `lsof` 的更多信息,请参阅 `lsof` 常见问题解答(常见问题解答部分给出了其位置)。

-b    导致 lsof 避免使用那些可能导致阻塞的内核函数——lstat(2)、[readlink]({filename}../../readlink)(2) 和 [stat]({filename}../../stat)(2)。

请参阅“阻塞与超时”和“避免内核阻塞”部分,以获取有关使用此选项的信息。

-c c      选择正在执行以字符 c 开头的命令的进程的文件列表。可以使用多个 -c 选项来指定多个命令。它们在参与 AND 选项选择之前,会组合成一个单独的 OR 集合。

如果 c 以 ^ 开头,则后面的字符指定一个进程名,该进程将被忽略(排除)。

如果 c 以斜杠(/)开头和结尾,则斜杠之间的字符将被解释为正则表达式。正则表达式中的 shell 元字符必须用引号括起来,以防止 shell 对其进行解释。闭合斜杠后面可以跟以下修饰符:

b     正则表达式是一个基本正则表达式。
i     忽略字母的大小写。
x     正则表达式是一个扩展正则表达式(默认)。

有关基本正则表达式和扩展正则表达式的更多信息,请参阅 lsof FAQ(FAQ 部分给出了其位置)。

首先测试简单的命令规范。如果测试失败,则应用命令正则表达式。如果简单的命令测试成功,则不会进行命令正则表达式测试。这可能会导致在指定了 lsof 的 -V 选项时,出现“找不到与正则表达式匹配的命令”的消息。

+c w      定义了与进程关联的 UNIX 命令名称中,UNIX 变体提供的初始字符的最大数量,这些字符将打印在“COMMAND”列中。(lsof 的默认值为九。)

请注意,许多 UNIX 变体不会向 lsof 提供所有命令名称字符,这些字符来自 lsof 获取命令名称的文件和结构。通常,这些变体限制了在这些来源中提供的字符数量。例如,Linux 2.4.27 和 Solaris 9 都将命令名称长度限制为 16 个字符。

如果 w 为零('0'),则将打印所有提供给 lsof 的 UNIX 变体的命令字符。

如果 w 小于列标题“COMMAND”的长度,则将其提高到该长度。

-C    禁用报告内核名称缓存中的任何路径名组件。有关更多信息,请参阅“内核名称缓存”部分。

+d s      导致 lsof 搜索目录 s 以及它包含的所有打开的实例和文件/目录,但它仅搜索 s 的顶层,不会向下遍历目录树。可以使用 +D D 选项来请求从目录 D 开始的完整目录树搜索。

处理 +d 选项时,除非同时指定 -x 或 -x l 选项,否则不会跟踪 s 中的符号链接。 并且,除非同时指定 -x 或 -x f 选项,否则不会搜索 s 的子目录上的文件系统挂载点上的开放文件。

注意:此选项的用户的权限限制了它只能搜索用户有权使用系统 stat(2) 函数检查的文件。

-d s 指定要从输出列表中排除或包含的文件描述符 (FD) 列表。 文件描述符以逗号分隔的集合 s 指定 - 例如,“cwd,1,3”、“^6,^2”。 (集合中不应有空格。)

如果集合中的所有条目都以 `^' 开头,则该列表是一个排除列表。 如果没有条目以 `^' 开头,则该列表是一个包含列表。 不允许混合列表。

集合中可以包含一个文件描述符编号范围,只要两个成员都不为空,并且都是数字,并且结束成员大于起始成员即可 - 例如,“0-7”或“3-10”。 如果它们带有 `^' 前缀,则可以为排除指定范围 - 例如,“^0-7”排除所有文件描述符 0 到 7。

在进行 AND 选项选择之前,多个文件描述符编号被连接成一个单独的 ORed 集合。

当集合中同时存在排除和包含成员时,lsof 会将其报告为错误,并以非零返回代码退出。

有关文件描述符名称的更多信息,请参阅“输出”部分中“文件描述符 (FD) 输出值”的描述。

fd 是一个用于指定整个可能的文件描述符编号范围的伪文件描述符名称。 fd 不会出现在输出的 FD 列中。

+D D 使 lsof 搜索目录 D 的所有开放实例以及它包含的所有文件和目录,直至其完整深度。

处理 +D 选项时,除非同时指定 -x 或 -x l 选项,否则不会跟踪 D 中的符号链接。 并且,除非同时指定 -x 或 -x f 选项,否则不会搜索 D 的子目录上的文件系统挂载点上的开放文件。

注意:此选项的用户的权限限制了它只能搜索用户有权使用系统 stat(2) 函数检查的文件。

进一步说明:lsof 可能会缓慢处理此选项,并且需要大量的动态内存来执行此操作。 这是因为必须向下遍历以 D 为根的整个目录树,为每个文件和目录调用 stat(2),构建它找到的所有文件的列表,并搜索该列表以匹配每个开放文件。 当目录 D 很大时,这些步骤可能需要很长时间,因此请谨慎使用此选项。

-D D 指示 lsof 使用设备缓存文件。 此选项的使用有时受到限制。 请参阅“设备缓存文件”部分和后续部分,以获取有关此选项的更多信息。

-D 必须后跟一个函数字母;该函数字母可以可选地后跟一个路径名。lsof 识别以下函数字母:

? - 报告设备缓存文件的路径
b - 构建设备缓存文件
i - 忽略设备缓存文件
r - 读取设备缓存文件
u - 读取并更新设备缓存文件

b、r 和 u 函数,连同路径名一起使用时,有时会受到限制。当这些函数受到限制时,它们不会出现在与 -h 或 -? 选项输出一起显示的 -D 选项的描述中。有关这些函数以及何时受到限制的更多信息,请参见“设备缓存文件”部分以及后面的部分。

? 函数报告 lsof 可以用于设备缓存文件的只读和写入路径、lsof 在构建设备缓存文件路径时将检查的任何环境变量的名称,以及个人设备缓存文件路径的格式。(根据你的 shell 要求,转义 `?' 字符。)

如果可用,b、r 和 u 函数可以后跟设备缓存文件的路径。标准默认值为用户 ID 执行 lsof 的主目录中的 .lsof_hostname,但这可能在编译和配置 lsof 时已更改。(-h 和 -? 选项的输出显示当前默认前缀 - 例如,``.lsof''。)后缀 hostname 是 gethostname(2) 返回的主机名的第一个组件。

如果可用,b 函数指示 lsof 在默认路径或指定的路径处构建新的设备缓存文件。

i 函数指示 lsof 忽略默认设备缓存文件,并通过直接调用内核来获取有关设备的信息。

r 函数指示 lsof 读取默认路径或指定路径处的设备缓存文件,但防止在不存在设备缓存文件或现有文件结构不正确时创建新的设备缓存文件。当指定不带路径名的 r 函数时,该函数始终可用;它可能会受到 lsof 进程权限的限制。

如果可用,u 函数指示 lsof 读取默认路径或指定路径处的设备缓存文件(如果可能),并在必要时重建它。当未指定 -D 选项时,这是默认的设备缓存文件函数。

+|-e s 从可能导致阻塞的内核函数调用中排除路径名为 s 的文件系统。+e 选项排除 [stat]({filename}../../stat)(2)、lstat(2) 和大多数 [readlink]({filename}../../readlink)(2) 内核函数调用。-e 选项仅排除 [stat]({filename}../../stat)(2) 和 lstat(2) 内核函数调用。可以使用单独的 +|-e 规范指定多个文件系统,并且每个文件系统都可以选择是否排除 [readlink]({filename}../../readlink)(2) 调用。

此选项目前仅针对 Linux 实现。

注意:此选项很容易被错误地应用于非目标文件系统,因为它使用路径名而不是更可靠的设备号和 inode 号。

(设备号和 inode 号通过可能阻塞的 stat(2) 内核调用获取,因此不可用,但请参阅 +|-m m 选项,这可能是一种提供设备号的替代方法。)请谨慎使用此选项,并完全指定要排除的文件系统的路径名。

当报告已排除的文件系统上的打开文件时,可能无法获取所有相关信息。因此,某些信息列将为空白,TYPE 列中的值将以“UNKN”开头,并在 NAME 列的末尾添加适用的排除选项(括号中)。(可以通过 +|-m m 选项提供一些设备号信息。)

+|-E +E 指定 Linux 管道、Linux UNIX 套接字、在本地主机上关闭的 Linux INET(6) 套接字、Linux 伪终端文件、Linux 中 POSIX 消息队列的实现以及 Linux eventfd 应显示其端点信息,并且端点文件的信息也应显示。

注意 1:只有当 -v 输出的“已启用功能”行包含 uxsockept 时,才可用 UNIX 套接字文件端点信息;只有当“已启用功能”行包含 ptyept 时,才可用伪终端端点信息。

注意 2:只有在 mqueue 文件系统已挂载时,才可用 POSIX 消息队列文件端点信息。

管道端点信息以“PID,cmd,FDmode”的形式显示在 NAME 列中,其中 PID 是端点进程 ID;cmd 是端点进程的命令;FD 是端点文件的文件描述符;mode 是端点文件的访问模式。

伪终端端点信息以“->/dev/ptsmin PID,cmd,FDmode”或“PID,cmd,FDmode”的形式显示在 NAME 列中。第一种形式用于主设备;第二种形式用于从设备。min 是从设备的次设备号;PID、cmd、FD 和 mode 与管道端点信息中的含义相同。注意:伪终端端点信息只有在 -v 输出的“已启用功能”行包含 ptyept 时才可用。此外,此功能适用于 Linux 内核 4.13.0 及更高版本。

UNIX 套接字文件端点信息以“type=TYPE ->INO=INODE PID,cmd,FDmode”的形式显示在 NAME 列中,其中 TYPE 是套接字类型;INODE 是连接的套接字的 inode 号;PID、cmd、FD 和 mode 与管道端点信息中的含义相同。注意:只有当 -v 输出的“已启用功能”行包含 uxsockept 时,才可用 UNIX 套接字文件端点信息。


INET 套接字文件末端信息将插入到 NAME 列中的值,格式为
`` -> PID,cmd,FDmode'',其中 PID、cmd、FD 和模式与管道末端信息中的相同。只有当套接字用于本地 IPC 时,才提供末端信息;两个末端都绑定到相同的本地 IPv4 或 IPv6 地址。

POSIX 消息队列文件末端信息以与管道相同的方式显示在 NAME 列中。

eventfd 末端信息以与管道相同的方式显示在 NAME 列中。此功能适用于 Linux 内核版本高于 5.2.0 的系统。

文件 NAME 列中可以出现多次此类信息。

-E 指定应显示支持末端的文件以及末端信息,但不显示末端文件本身。

+|-f [cfgGn]
f 本身明确了如何解释路径名参数。后跟 c、f、g、G 或 n(以任何组合形式)时,它指定应启用(`+`)或禁用(`-`)内核文件结构信息的列表。

通常,路径名参数被视为文件系统名称,如果它与 [mount]({filename}../../mount)(8) 报告的挂载目录名称匹配,或者它表示挂载输出中与挂载目录名称关联的块设备。当指定 +f 时,所有路径名参数都将被视为文件系统名称,并且 lsof 会抱怨任何不符合要求的参数。这在文件系统名称(挂载设备)不是块设备时可能很有用。对于某些 CD-ROM 文件系统,这种情况会发生。

当单独指定 -f 时,所有路径名参数都将被视为简单文件。因此,例如,``-f -- /`` 参数指示 lsof 搜索具有 `/` 路径名的打开文件,而不是根目录 `/` 中的所有打开文件。

务必小心,确保正确终止 +f 和 -f,并且不要在其后跟一个字符(例如文件或文件系统名称),该字符可能会被解释为参数。例如,在 +f 和 -f 之后使用 ``--``,如下所示。

$ lsof +f -- /file/system/name
$ lsof -f -- /file/name

使用 +f [cfgGn] 选项形式请求的内核文件结构信息列表通常会被禁用,并且对于某些变体(例如,基于 /proc 的 Linux 内核版本低于 2.6.22)而言,该列表可能无法完全或部分提供。当 f 前面的字符是加号(`+`)时,这些字符请求文件结构信息:

c 文件结构使用计数(非 Linux)
f 文件结构地址(非 Linux)
g 文件标志缩写(Linux 2.6.22 及更高版本)

缩写。 C 代码中的标志(请参阅 open(2))

W O_WRONLY
RW O_RDWR
CR O_CREAT
EXCL O_EXCL
NTTY O_NOCTTY
TR O_TRUNC
AP O_APPEND
ND O_NDELAY
SYN O_SYNC
ASYN O_ASYNC
DIR O_DIRECT
DTY O_DIRECTORY
NFLK O_NOFOLLOW
NATM O_NOATIME
DSYN O_DSYNC
RSYN O_RSYNC
LG O_LARGEFILE
CX O_CLOEXEC
TMPF O_TMPFILE

G    以十六进制显示文件标志(Linux 2.6.22 及更高版本)
n    文件结构节点地址(非 Linux)

当使用负号前缀(`-\')时,相同的字符会禁用指示值的列出。

文件结构地址、使用计数、标志和节点地址可用于更轻松地检测由子进程继承的相同文件以及由不同进程使用的相同文件。lsof 的列输出可以按包含这些值的列进行排序,以识别相同的文件使用情况,或者 lsof 字段输出可以由 AWK 或 Perl 后处理脚本或 C 程序进行解析。

-F f    指定字符列表 f,以选择要为另一个程序处理的输出字段,并指定终止每个输出字段的字符。要输出的每个字段都使用 f 中的单个字符指定。字段终止符默认为 NL,但可以更改为 NUL(000)。请参阅“为其他程序输出”部分,了解字段标识符的描述和字段输出过程。

当字段选择字符列表为空时,将选择所有标准字段(不包括原始设备字段、安全上下文和区域字段,以保持兼容性),并使用 NL 字段终止符。

当字段选择字符列表仅包含零(`0`),则将选择所有字段(不包括原始设备字段),并使用 NUL 终止符字符。

其他字段组合及其关联的字段终止符字符必须使用 f 中的显式条目进行设置,如“为其他程序输出”部分所述。

当字段选择字符标识 lsof 通常不列出的项目(例如,使用 -R 规范字段字符 -F 标识的 PPID),也会选择该项目的列出。

当字段选择字符列表包含单个字符 `?` 时,lsof 将显示字段标识符的帮助列表。(根据需要转义 ? 字符,如您的 shell 所需。)

-g [s]   排除或选择要列出的文件,这些文件属于其可选进程组 ID(PGID)编号位于逗号分隔的集合 s 中的进程 - 例如,“123”或“123,\^456”。(集合中不应有空格。)

以 `^\' 开头的 PGID 编号表示排除。

多个 PGID 编号在一个 ORed 集中连接起来,然后再参与 AND 选项选择。但是,PGID 排除在不进行 OR 或 AND 的情况下应用,并在应用其他选择标准之前生效。

^ g 选项还会启用 PGID 编号的输出显示。如果未指定 PGID 集合,则仅执行此操作。

-H    指示 `lsof` 打印可读大小,例如 123.4K 456.7M。

-i [i]   选择要列出的文件,这些文件的任何 Internet 地址都与 i 中指定的地址匹配。如果未指定地址,则此选项选择所有 Internet 和 25(HP-UX)网络文件的列出。

如果指定了 -i4 或 -i6,但后面没有跟地址,则仅显示指示的 IP 版本(IPv4 或 IPv6)的文件。(IPv6 规范只能在 UNIX 变体支持 IPv6 时使用,具体方法是查看 lsof 的 -h 或 -? 输出中是否包含“[46]”和“IPv[46]”。)依次指定 -i4,然后是 -i6,与指定 -i 效果相同,反之亦然。在指定 -i 之后指定 -i4 或 -i6,与单独指定 -i4 或 -i6 效果相同。

可以使用多个 -i 选项指定多个地址(最多 100 个)。它们会合并为一个单独的 ORed 集合,然后再参与 AND 选项选择。

互联网地址的指定形式如下(方括号中的项目是可选的):

[46][协议][@主机名|主机地址][:服务|端口]

其中:
46 指定 IP 版本,IPv4 或 IPv6,
适用于以下地址。
'6' 只能在 UNIX 变体支持 IPv6 时指定。
如果未指定 '4' 或 '6',则以下地址
适用于所有 IP 版本。
协议是协议名称 - TCP、UDP 或 UDPLITE。
主机名是互联网主机名。除非指定了
特定的 IP 版本,否则将选择与所有版本
的主机名关联的开放网络文件。
主机地址是数字 IPv4 互联网地址,采用
点分形式;或者是一个数字 IPv6 地址,采用
冒号形式,如果 UNIX 变体支持 IPv6,则用方括号括起来。
当选择 IP 版本时,只能指定其数字地址。
服务是 /etc/services 中的名称 - 例如,smtp,或一个列表。
端口是端口号,或一个列表。

只能在 UNIX 变体支持 IPv6 时才能使用 IPv6 选项。要查看该变体是否支持 IPv6,请运行 lsof 并指定 -h 或 -?(帮助)选项。如果显示的 -i 选项描述中包含“[46]”和“IPv[46]”,则表示支持 IPv6。

如果网络文件选择限制为 IPv6,则不能指定 IPv4 主机名和地址,使用 -i 6。如果网络文件选择限制为 IPv4,则不能指定 IPv6 主机名和地址,使用 -i 4。当开放的 IPv4 网络文件的地址映射到 IPv6 地址时,开放文件的类型将是 IPv6,而不是 IPv4,并且其显示将由“6”选择,而不是“4”。

必须提供至少一个地址组件 - 4、6、协议、主机名、主机地址或服务。`@` 字符始终需要位于主机规范的前面;`:` 字符始终需要位于端口规范的前面。指定主机名或主机地址。指定服务名列表或端口号列表。如果指定了服务名列表,则如果 TCP、UDP 和 UDPLITE 的端口号不同,则协议也可能需要指定。对于协议,可以使用任何大小写形式。

服务名称和端口号可以组合在一个列表中,列表中的条目用逗号分隔,数值范围条目用减号分隔。 不能有嵌入的空格,并且所有服务名称必须属于指定的协议。 由于服务名称可能包含嵌入的减号,因此范围的起始条目不能是服务名称; 但是,它可以是端口号。

以下是一些示例地址:

-i6 - 仅 IPv6
TCP:25 - TCP 和端口 25
@1.2.3.4 - Internet IPv4 主机地址 1.2.3.4
@[3ffe:1ebc::1]:1234 - Internet IPv6 主机地址
3fe:1ebc::1, 端口 1234
UDP:who - UDP who 服务端口
_:513 - TCP,端口 513 和主机名 lsof.itap
tcp@foo:1-10,smtp,99 - TCP,端口 1 到 10,
服务名称 smtp,端口 99,主机名 foo
tcp@bar:1-smtp - TCP,端口 1 到 smtp,主机 bar
:time - 无论是 TCP、UDP 还是 UDPLITE time 服务端口

-K k 选择要列出的进程的任务(线程),在支持任务(线程)报告的方言中。 (如果帮助输出(即 -h 或 -?选项的输出)显示此选项,则该方言支持任务(线程)报告。)

如果 -K 后面跟着一个值 k,则必须是 ``i''。 这会导致 lsof 忽略任务,尤其是在默认的、列出所有内容的情况下,如果没有指定其他选项。

当在 Linux 上同时指定 -K 和 -a 时,并且如果通过其他选项选择了主进程的任务,则主进程也将被列出,就像它是一个任务一样,但没有任务 ID。(请参阅输出部分中 TID 列的描述。)

在 FreeBSD 版本支持线程的情况下,所有线程都将与其 ID 一起列出。

通常,线程和任务会继承调用者的文件,但可能会关闭一些并打开其他文件,因此 lsof 始终报告所有线程和任务的打开文件。

-k k 指定一个内核名称列表文件 k,而不是 /vmunix、/mach 等。 -k 在 IBM RISC/System 6000 上的 AIX 上不可用。

-l 禁用将用户 ID 转换为登录名的转换。 当登录名查找无法正常工作或速度较慢时,它也很有用。

+|-L [l] 启用(`+`)或禁用(`-`)文件链接计数列表,在可用时(例如,它们不可用于套接字或大多数 FIFO 和管道)。

当指定 +L 但不带后面的数字时,将列出所有链接计数。 当指定 -L(默认值)时,不会列出任何链接计数。

当 +L 后面跟着一个数字时,将仅列出链接计数小于该数字的文件。 (不能在 -L 后面跟着数字)。 形式为“+L1”的规范将选择已取消链接的打开文件。 形式为“+aL1 <file_system>”的规范将选择指定文件系统上已取消链接的打开文件。

对于其他链接计数比较,请使用字段输出 (-F) 和后处理脚本或程序。

+|-m m 指定一个替代内核内存文件或激活挂载表补充处理。

选项 -m m 指定一个内核内存文件 m,以代替 /dev/kmem/dev/mem——例如,一个崩溃转储文件。

选项 +m 请求将一个挂载补充文件写入标准输出文件。所有其他选项将被静默忽略。

挂载补充文件对于每个已挂载的文件系统都有一行,其中包含已挂载的文件系统目录,后跟一个空格,然后是十六进制格式的设备号“0x”——例如:

/ 0x801

^ sof 可以使用挂载补充文件来获取文件系统的设备号,当它无法通过 stat(2) 或 lstat(2) 获取时。

选项 +m mm 指定为挂载补充文件。

注意:`+m` 和 `+m m` 选项并非所有受支持的方言都可用。请检查 `lsof` 的 `-h` 或 `-?` 选项的输出,以查看 `+m` 和 `+m m` 选项是否可用。

`+|-M` 启用 (+) 或禁用 (-) 对本地 TCP、UDP 和 UDPLITE 端口的 portmapper 注册信息的报告,其中支持端口映射。 (有关 portmapper 注册信息报告的更多信息,请参见本选项描述的最后一段。)

默认报告模式由 lsof 构建器通过方言的 machine.h 头文件中的 HASPMAPENABLED 宏来设置;lsof 以禁用 HASPMAPENABLED 宏的形式分发,因此默认情况下禁用 portmapper 报告,并且必须使用 +M 请求启用。指定 lsof-h-? 选项将报告默认模式。禁用已禁用的 portmapper 注册信息或启用已启用的 portmapper 注册信息是可以接受的。当启用 portmapper 注册信息报告时,lsof 会在紧随端口号或服务名称之后(用方括号括起来)显示本地 TCP、UDP 或 UDPLITE 端口的 portmapper 注册信息(如果有的话)——例如,:1234[name]:name[100083]。注册信息可能是名称或数字,具体取决于注册程序在向 portmapper 注册端口时提供的内容。

当启用 portmapper 注册信息报告时,lsof 可能会运行得稍微慢一些,甚至在访问 portmapper 变得拥堵或停止时被阻塞。反转报告模式,以确定 portmapper 注册信息报告是否正在降低或阻止 lsof 的运行。

为了进行 portmapper 注册信息报告,lsof 认为 TCP、UDP 或 UDPLITE 端口是本地端口,如果:它位于其包含的内核结构的本地部分;或者,如果它位于其包含的内核结构的外部部分,并且本地和外部 Internet 地址相同;或者,如果它位于其包含的内核结构的外部部分,并且外部 Internet 地址是 INADDR_LOOPBACK (127.0.0.1)。 此规则可能会导致 lsof 忽略在具有多个接口的机器上,外部 Internet 地址位于与本地地址不同的接口上的某些外部端口。


请参阅 [lsof] FAQ(FAQ 部分给出了其位置),以获取有关端口映射器注册报告问题的更多讨论。

端口映射器注册报告仅在具有 RPC 标头文件的方言上受支持。(某些使用 GlibC 2.14 的 Linux 发行版没有这些标头文件。)当支持端口映射器注册报告时,-h 或 -? 帮助输出将显示 +|-M 选项。

-n       禁止将网络号码转换为主机名以进行网络文件显示。禁止转换可能会使 [lsof] 运行更快。当主机名查找无法正常工作时,它也很有用。

-N       选择要列出的 NFS 文件。

-o       指示 [lsof] 始终显示文件偏移量。它会更改 SIZE/OFF 输出列标题为 OFFSET。请注意:在某些 UNIX 方言中,[lsof] 无法从其内核数据源中获取准确或一致的文件偏移量信息,有时仅针对特定类型的文件(例如,套接字文件)。请参阅 [lsof] FAQ(FAQ 部分给出了其位置),以获取更多信息。

-o 和 -s 选项是互斥的;它们不能同时指定。当两者都没有指定时,[lsof] 将显示适当且可用的值 - 大小或偏移量 - 用于文件类型。

-o o     定义在文件偏移量后面的十进制数字数 (o),然后再切换到“0x...”格式。零 (o) 值(无限制)指示 [lsof] 对所有偏移量输出使用“0t”格式。

此选项不会指示 [lsof] 始终显示偏移量;要执行此操作,请指定 -o(不带尾随数字)。-o o 仅指定混合大小和偏移量或仅偏移量输出中“0t”之后的位数。因此,例如,要指示 [lsof] 始终显示偏移量,并使用 10 个十进制数字,请使用:

-o -o 10
或
-oo10

“0t” 之后允许的默认数字通常为 8,但可能已由 [lsof] 构建者更改。请参阅 -h 或 -? 选项输出中 -o o 选项的说明,以确定生效的默认值。

-O       指示 [lsof] 绕过其用于避免被某些内核操作阻塞的策略 - 即,在分叉的子进程中执行这些操作。请参阅“BLOCKS AND TIMEOUTS”和“AVOIDING KERNEL BLOCKS”部分,以获取有关可能阻塞 [lsof] 的内核操作的更多信息。

虽然使用此选项会减少 [lsof] 启动开销,但它也可能导致内核对函数没有响应时,[lsof] 挂起。请谨慎使用此选项。

-p s     排除或选择要列出的文件的进程,这些进程的可选进程 ID (PID) 位于逗号分隔的集合 s 中 - 例如,“123”或“123,^456”。(集合中不应有空格。)

以 `^`(否定)开头的 PID 编号表示排除。

多个进程 ID 编号在一个 ORed 集合中连接,然后参与 AND 选项选择。但是,PID 排除会在应用其他选择标准之前应用,且不进行 OR 或 AND 操作。

-P 阻止将端口号转换为端口名称,用于网络文件(通常从 /etc/services 中学习映射)。阻止转换可能会使 lsof 运行得稍微快一些。当端口名称查找无法正常工作时,它也很有用。

-Q 忽略失败的搜索词。当 lsof 被告知搜索文件的用户、设备的
用户、特定的 PID 或该 PID 使用的特定协议时,如果任何搜索结果为空,lsof 将返回错误。-Q 选项将更改此行为,以便 lsof 仍然返回成功的退出代码(0),即使任何搜索结果为空。此外,缺少的搜索词不会报告到 stderr。

+|-r [t[c<N>][m<fmt>]]
将 lsof 置于重复模式。lsof 会列出由其他选项选择的打开的文件,延迟 t 秒(默认为十五秒),然后重复列出,延迟并重复列出,直到通过该选项的前缀定义的条件停止。

如果前缀是 `\`-,重复模式将是无限的。必须使用中断或退出信号终止 lsof。`\`c<N>\` 用于指定重复的限制;如果迭代次数达到 `<N>`,lsof 将自行停止。

如果前缀是 \+,重复模式将在第一次循环中列出所有打开的文件,或者在 lsof 通过中断或退出信号停止时结束。当重复模式因未列出任何文件而结束时,如果曾经列出过任何打开的文件,则进程退出代码将为零;如果没有列出过任何文件,则为一。

Lsof 标记每个列表的结尾:如果正在进行字段输出(指定了 -F 选项),则默认标记为 m;否则,默认标记为 ``========''。标记后跟一个换行符 (NL)。

可选的 "m<fmt>" 参数指定标记行的格式。在 `\`m\` 之后出现的 `<fmt>` 字符被解释为 strftime(3) 函数的格式说明符,前提是该函数的方言的 C 库中同时存在 strftime(3) 函数和 localtime(3) 函数。请参阅 strftime(3) 文档,了解其格式说明符中可以包含的内容。请注意,当使用 -F 选项请求字段输出时,`<fmt>` 不能包含换行符格式 `\`%n''`。另请注意,当 `<fmt>` 包含空格或其他会影响 shell 解释参数的字符时,必须适当地引用 `<fmt>`。

重复模式减少了 lsof 的启动开销,因此比从 shell 脚本中重复调用 lsof 更有效。

为了最有效地使用重复模式,请将 +|-r 与其他 lsof 选择选项一起使用,以使 lsof 进行的内核内存访问量保持在最低水平。过滤在进程级别进行的选项(例如,-c、-g、-p、-u)是最有效的选择器。


重复模式在与字段输出(参见 -F 选项的说明)结合使用时非常有用,并且可以与监督的 awk 或 Perl 脚本,或者 C 程序一起使用。

-R 选项指示 lsof 在 PPID 列中列出父进程 ID 编号。

-s [p:s] 选项,单独使用时,指示 lsof 始终显示文件大小。它会更改 SIZE/OFF 输出列的标题为 SIZE。如果文件没有大小,则不显示任何内容。

可选的 -s p:s 形式仅适用于选定的方言,并且只有当 -h 或 -? 帮助输出中列出时才可用。

当可选形式可用时,s 之后可以跟一个协议名称 (p),可以是 TCP 或 UDP,然后是一个冒号 (:) 和一个逗号分隔的协议状态名称列表,该选项会导致 lsof 排除打开的 TCP 和 UDP 文件,如果它们的状态名称在列表中,则在状态名称前加上一个 `^`;或者如果它们的状态名称不在列表中,则包含这些文件。

支持此选项的方言可能仅支持一个协议。当指定一个不受支持的协议时,将显示一条消息,指示该协议的状态名称不可用。

当定义了包含列表时,只有状态名称在列表中的网络文件才会出现在 lsof 的输出中。因此,指定一个状态名称意味着只有状态名称为该名称的网络文件才会列出。

协议或状态名称的大小写不重要,但不能有空格,并且分隔协议名称 (p) 和状态名称列表 (s) 的冒号 (:) 是必需的。

如果只想列出 TCP 和 UDP 文件,并且受指定的排除和包含规则控制,则必须同时指定 -i 选项。如果只想列出单个协议的文件,请将其名称作为参数添加到 -i 选项中。

例如,要仅列出状态为 LISTEN 的 TCP 网络文件,请使用:
-iTCP -sTCP:LISTEN

或者,例如,要列出状态为除 Idle 之外的所有 UDP 状态的网络文件,请使用:

-iUDP -sUDP:^Idle

状态名称因 UNIX 方言而异,因此无法提供完整的列表。一些常见的 TCP 状态名称包括:CLOSED、IDLE、BOUND、LISTEN、ESTABLISHED、SYN_SENT、SYN_RCDV、ESTABLISHED、CLOSE_WAIT、FIN_WAIT1、CLOSING、LAST_ACK、FIN_WAIT_2 和 TIME_WAIT。两个常见的 UDP 状态名称是 Unbound 和 Idle。

请参阅 lsof FAQ(FAQ 部分给出了其位置),以获取有关如何使用协议状态排除和包含的更多信息,包括示例。

-o(没有后面的数字计数)选项和 -s 选项(没有后面的协议和状态名称列表)是互斥的;不能同时指定这两个选项。当两者都没有指定时,lsof 会显示适合该文件类型的适当值——大小或偏移量。

由于某些类型的文件没有真实的大小——套接字、FIFO、管道等——lsof 会显示与其关联的内核缓冲区中的内容量作为它们的大小(如果可能)。


-S [t]   指定一个可选的内核函数(例如 `lstat(2)`、`[readlink]({filename}../../readlink)(2)` 和 `[stat]({filename}../../stat)(2)`)的超时秒数,这些函数可能会导致死锁。最小值为 2;默认值为 15;如果未指定值,则使用默认值。

有关更多信息,请参阅“块和超时”部分。

-T [t]   控制某些 TCP/TPI 信息的报告,这些信息也由 `[netstat]({filename}../../netstat)(1)` 报告,并显示在网络地址之后。在正常输出中,这些信息将显示在括号中,每个项目(除了 TCP 或 TPI 状态名称)都由一个关键字标识,后跟一个“=”号,并用单个空格分隔:

<TCP 或 TPI 状态名称>
QR=<读取队列长度>
QS=<发送队列长度>
SO=<套接字选项和值>
SS=<套接字状态>
TF=<TCP 标志和值>
WR=<读取窗口长度>
WW=<写入窗口长度>

并非所有值都为所有 UNIX 变体报告。如果可用,项目值将显示在项目名称和“=”号之后。

当字段输出模式生效时(请参见“其他程序的输出”),每个项目都将显示为一个以“T”开头的字段。

-T 后面不跟任何键字符会禁用 TCP/TPI 信息报告。

-T 后面跟键字符会选择报告特定的 TCP/TPI 信息:

f    选择报告套接字选项、状态和值以及 TCP 标志和值。
q    选择报告队列长度。
s    选择报告连接状态。
w    选择报告窗口大小。

并非所有选择都适用于所有 UNIX 变体。状态可以选择所有变体,并且默认情况下会报告状态。使用 -h-? 选项的帮助输出将显示哪些选择可用于 UNIX 变体。

当使用 -T 选择信息时(即,它后面跟有一个或多个选择字符),默认情况下会禁用状态的显示,并且必须再次在 -T 后面跟随的字符中明确选择状态。(在这种情况下,默认设置等同于 -Ts。)例如,如果需要队列长度和状态,请使用 -Tqs

套接字选项、套接字状态、某些套接字值、TCP 标志和一个 TCP 值(如果 UNIX 变体中可用)可以以该变体中的标头文件中(通常是 `<sys/socket.h>`、`<sys/socketvar.h>` 和 `<netinet/tcp_var.h>`)常见的名称形式报告——通常是 `SO_`、`so_`、`SS_`、`TCP_` 和 `TF_`。请查阅这些标头文件以了解标志、选项、状态和值的含义。

``SO=''`` 位于套接字选项和值之前;``SS=''`` 位于套接字状态之前;``TF=''`` 位于 TCP 标志和值之前。

如果标志或选项具有值,则该值将显示在“=”号和名称之后——例如,SO=LINGER=5''、SO=QLIM=5''、``TF=MSS=512''。以下七个值可能会被报告:

名称 报告的 描述(常用符号)


KEEPALIVE  保持活动时间 (SO_KEEPALIVE)
LINGER  延迟时间 (SO_LINGER)
MSS  最大分段大小 (TCP_MAXSEG)
PQLEN  部分监听队列中的连接数
QLEN  已建立的监听队列中的连接数
QLIM  已建立的监听队列的限制
RCVBUF  接收缓冲区长度 (SO_RCVBUF)
SNDBUF  发送缓冲区长度 (SO_SNDBUF)

关于特定 UNIX 变体可能显示的套接字选项和值、套接字状态以及 TCP 标志和值的详细信息,请参阅 lsof FAQ 中“为什么 lsof 不报告我的变体中套接字选项、套接字状态和 TCP 标志和值?”和“为什么 lsof 不报告我的变体中部分监听队列连接计数?”问题的答案。(FAQ 部分给出了其位置。)在 Linux 上,此选项还会打印 UNIX 域套接字的狀態。

-t  生成简洁的输出,仅包含进程标识符(不带标题),以便于以编程方式使用。例如:

# 重新加载任何使用旧 SSL 的进程
lsof -t /lib/*/libssl.so.* | xargs -r kill -HUP

# 获取进程列表,然后对其进行迭代(仅限 Bash)
mapfile -t pids < <(
lsof -wt /var/log/your.log
)
for pid in "${pids[@]}" ; do
your_command -p "$pid"
done

-t 选项隐含 -w 选项。

-u s  选择要列出的文件的用户,其登录名或用户 ID 位于逗号分隔的集合 s 中 - 例如,“abe”或“548,root”。(集合中不应有空格。)

多个登录名或用户 ID 在参与 AND 选项选择之前,将连接到一个 ORed 集合中。

如果登录名或用户 ID 前面有“^”,则变为否定 - 即,拥有该登录名或用户 ID 的进程的文件将永远不会被列出。被否定的登录名或用户 ID 选择既不与其他选择进行 AND 运算,也不进行 OR 运算;它在所有其他选择之前应用,并绝对排除列出该进程的文件。例如,要指示 lsof 排除属于 root 进程的文件,请指定“-u^root”或“-u^0”。

-U  选择要列出的 UNIX 域套接字文件。

-v  选择要列出的 lsof 版本信息,包括:修订号;构建 lsof 二进制文件的日期;构建二进制文件的用户及其位置;用于构建 lsof 二进制文件的编译器的名称;在可以轻松获取时,编译器的版本号;以及用于构建 lsof 二进制文件的编译器和加载器标志;以及系统信息,通常是 uname -a 选项的输出。

-V  指示 lsof 指示它被要求列出的项目,但未能找到 - 命令名称、文件名、Internet 地址或文件、登录名、NFS 文件、PID、PGID 和 UID。

当其他选项与搜索选项进行 AND 运算时,或者编译时选项限制了某些文件的列出,lsof 可能不会报告它未能找到搜索项,因为 ANDed 选项或编译时选项会阻止列出包含已找到的搜索项的打开文件。

例如,lsof -V -iTCP@foobar -a -d 999 可能不会报告无法找到在 TCP@foobar 处的打开文件,并且如果不存在文件描述符为 99 的文件,则可能不会列出任何文件。 类似的情况也会发生在编译时定义了 HASSECURITYHASNOSOCKSECURITY,并且它们阻止列出打开的文件时。

+|-w 启用 (+) 或禁用 (-) 警告消息的抑制。

lsof 构建者可以选择默认情况下禁用或启用警告消息。 默认警告消息状态在 -h-? 选项的输出中指示。 在警告消息已经禁用时禁用它们,或者在警告消息已经启用时启用它们是可以接受的。

^ t 选项意味着 -w 选项。

-x [fl] 可以与 +d 和 +D 选项一起使用,以指示在扫描目录 (+d) 或目录树 (+D) 时,处理过程中是否跨越符号链接和/或文件系统挂载点。

如果 -x 选项单独指定,没有后面的参数,则启用跨越符号链接和文件系统挂载点的处理。 请注意,当 -x 选项在没有参数的情况下指定时,下一个参数必须以 -+ 开头。

可选的 'f' 参数启用文件系统挂载点跨越处理;'l',启用符号链接跨越处理。

^ x 选项不能在不同时提供 +d 或 +D 选项的情况下使用。

-X 这是一个特定于方言的选项。

AIX: 此 IBM AIX RISC/System 6000 选项请求报告执行的文本文件和共享库引用。

警告:由于此选项使用内核 readx() 函数,因此在繁忙的 AIX 系统上使用它可能会导致应用程序进程完全挂起,以至于无法终止或停止。 我从未见过这种情况发生过,也没有收到任何关于这种情况的报告,但我认为存在这种可能性。

默认情况下,禁用 readx() 的使用。 在 AIX 5L 及更高版本上,lsof 可能需要 setuid-root 权限才能执行此选项请求的操作。

lsof 构建者可以指定 -X 选项仅限于其实际 UID 为 root 的进程。 如果这样做了,则 -X 选项不会出现在 -h-? 帮助输出中,除非 lsof 进程的实际 UID 为 root。 默认的 lsof 发行版允许任何 UID 指定 -X,因此默认情况下它会出现在帮助输出中。

当禁用 AIX readx() 使用时,lsof 可能无法报告所有文本和加载器文件引用信息,但它也可能避免加剧 AIX 内核目录搜索内核错误,这被称为过时段标识错误。

^ eadx() 函数,由 lsof 或任何其他程序用于访问内核虚拟内存的某些部分,可能会触发过时段标识错误。 它可能导致内核的 dir_search() 函数错误地认为文件系统目录的内存副本的一部分已被设置为零。 另一个应用程序进程(不同于 lsof)请求内核搜索目录 - 例如,通过使用 open(2) - 可能会导致 dir_search() 永远循环,从而使应用程序进程挂起。


请查阅 lsof 的 FAQ(FAQ 部分给出了其位置)以及 lsof 发行版的 00README 文件,以获取有关 Stale Segment ID 错误的更完整描述、其 APAR 以及定义 readx() 用法以编译 lsof 的方法。

Linux: 此 Linux 选项要求 lsof 忽略所有打开的 TCP、UDP 和 UDPLITE IPv4 和 IPv6 文件的信息报告。

当系统具有非常多的打开的 TCP、UDP 和 UDPLITE 文件时,此 Linux 选项最有用,因为处理 /proc/net/tcp* 和 /proc/net/udp* 文件中的这些文件信息会花费 lsof 较长时间,并且这些信息的报告可能不感兴趣。

请谨慎使用此选项,并且仅在确定您想要 lsof 显示的信息与打开的 TCP、UDP 或 UDPLITE 套接字文件无关时才使用。

Solaris 10 及更高版本: 此 Solaris 10 及更高版本的选项要求报告已删除文件的缓存路径,即使用 rm(1) 或 unlink(2) 删除的文件。

缓存路径后跟字符串 `` (deleted),以表明文件被打开的路径已被删除。

由于对路径进行的任何中间更改(即使用 mv(1) 或 rename(2) 重命名),都不会记录在缓存路径中,因此 lsof 报告的内容仅为文件被打开的路径,而不是其可能不同的最终路径。

-z [z]   指定如何处理 Solaris 10 及更高版本的区域信息。

如果没有后续参数(例如,NO z),则该选项指定应在 ZONE 输出列中列出区域名称。

-z 选项可以后跟一个区域名称,z。这将导致 lsof 仅列出该区域中进程的打开文件。可以指定多个 -z z 选项和参数对,以形成一个命名区域列表。任何区域中任何进程的任何打开文件都将被列出,但这取决于其他选项和参数指定的条件。

-Z [Z]   指定如何处理 SELinux 安全上下文。如果正在运行的 Linux 内核中禁用了 SELinux,则禁用它和 'Z' 字段输出字符的支持。

有关 'Z' 字段输出字符的更多信息,请参阅其他程序的输出。

如果没有后续参数(例如,NO Z),则该选项指定应在 SECURITY-CONTEXT 输出列中列出安全上下文。

-Z 选项可以后跟一个通配符安全上下文名称,Z。这将导致 lsof 仅列出该安全上下文中的进程的打开文件。可以指定多个 -Z Z 选项和参数对,以形成一个安全上下文列表。任何安全上下文中的任何进程的任何打开文件都将被列出,但这取决于其他选项和参数指定的条件。请注意,Z 可以是 A:B:C 或 \*:B:C 或 A:B:\* 或 \*:*\:C,以匹配 A:B:C 上下文。

--       双重减号选项是一个标记,用于指示键控选项的结束。
例如,当第一个文件名以减号开头时,可以使用它。 也可以在最后一个键控选项的值缺失时,通过在下一个选项中放置一个减号来表示,然后再开始列出文件名。

names    这些是特定文件的路径名,将在使用之前解析符号链接。

第一个名称可以与前面的选项通过 ``--'' 选项分隔。

如果某个名称是文件系统挂载的目录或文件系统的设备, lsof 将列出文件系统中打开的所有文件。 要被视为文件系统, 该名称必须与 mount(8) 输出中的挂载目录名称匹配,或者与与挂载目录名称关联的块设备名称匹配。 可以使用 +|-f 选项来强制 lsof 将某个名称视为文件系统标识符 (+f) 或简单文件 (-f)。

如果某个名称是通往目录的路径,并且该目录不是文件系统的挂载目录名称, 则它将被视为普通文件一样处理——即,其列表仅限于将该文件作为文件或作为进程特定目录(例如根目录或当前工作目录)打开的进程。 要请求 lsof 查找目录名称内的打开文件,请使用 +d s 和 +D D 选项。

如果某个名称是复用文件系列的基本名称——例如,AIX 上的 /dev/pt[cs],lsof 将列出设备上所有打开的关联复用文件——例如,/dev/pt[cs]/1、/dev/pt[cs]/2 等。

如果某个名称是 UNIX 域套接字名称,lsof 通常会通过名称的字符进行搜索——完全按照名称在内核套接字结构中指定的记录方式进行搜索。(对于 Linux,请参见下一段的例外情况。) 指定相对路径——例如,./file——而不是文件的绝对路径——例如,/tmp/file——将不起作用,因为 lsof 必须将您指定的字符与它在内核 UNIX 域套接字结构中找到的内容进行匹配。

如果某个名称是 Linux UNIX 域套接字名称,则在一种情况下,lsof 能够通过其设备和 inode 号进行搜索,从而允许名称是相对路径。 这种情况要求创建套接字的进程使用绝对路径——即,以斜杠 ('/') 开头的路径,并且该路径存储在 /proc/net/unix 文件中;并且要求 lsof 能够通过成功的 stat(2) 系统调用来获取 /proc/net/unix 中绝对路径和名称的设备和节点号。 当满足这些条件时,lsof 将能够搜索 UNIX 域套接字,即使在名称中指定了指向它的某些路径。 因此,例如,如果路径是 /dev/log,并且在工作目录为 /dev 时启动 lsof 搜索,则名称可以是 ./log。

如果名称不属于上述任何一种,lsof 将列出所有打开的文件,其设备号和 inode 与指定路径名匹配。

如果您还指定了 -b 选项,则您可以安全地指定的唯一名称是您的挂载表提供替代设备号的文件系统。请参阅“避免内核阻塞”和“替代设备号”部分以获取更多信息。

多个文件名以单个 OR 集合的形式连接起来,然后参与 AND 选项的选择。

AFS

^ sof 支持识别以下 AFS 协议(以及 AFS 版本)的文件:

AIX 4.1.4 (AFS 3.4a)
HP-UX 9.0.5 (AFS 3.4a)
Linux 1.2.13 (AFS 3.3)
Solaris 2.[56] (AFS 3.4a)

它可能可以识别其他版本的这些协议中的 AFS 文件,但尚未进行测试。根据 AFS 的实现方式,lsof 可能可以识别其他协议中的 AFS 文件,或者可能难以识别受支持协议中的 AFS 文件。

当 AFS 内核支持通过动态模块实现时,并且这些模块的地址不出现在内核的变量名列表中,lsof 可能难以识别受支持协议中 AFS 文件的所有方面。在这种情况下,lsof 可能需要推测 AFS 文件的身份,并且可能无法从内核中获取计算 AFS 卷节点号所需的卷信息。当 lsof 无法计算卷节点号时,它会在 NODE 列中报告空白。

在某些 lsof 协议实现中,可以使用 -A A 选项来指定包含动态模块内核地址的名称列表文件。如果此选项可用,它将在 lsof 的帮助输出中列出,该输出是在响应 -h-? 时显示的。

请参阅 lsof 常见问题解答(FAQ 部分给出了其位置),以获取有关动态模块、其符号以及它们如何影响 lsof 选项的更多信息。

由于 AFS 路径查找似乎不参与内核的名称缓存操作,因此 lsof 无法识别 AFS 文件的路径名组件。

安全性

^ sof 有三个功能可能引起安全问题。首先,其默认编译模式允许任何人使用它列出所有打开的文件。其次,默认情况下,它会在执行 lsof 的实际用户 ID 的主目录中创建一个用户可读且用户可写的设备缓存文件。(可以禁用“列出所有打开的文件”和“设备缓存”功能,方法是在编译 lsof 时进行设置。)第三,其 -k-m 选项指定了替代的内核名称列表或内存文件。

限制列出所有打开的文件由编译时 HASSECURITYHASNOSOCKSECURITY 选项控制。当定义了 HASSECURITY 时,lsof 仅允许 root 用户列出所有打开的文件。非 root 用户只能列出与 lsof 进程的实际用户 ID(即用户登录时使用的用户 ID)具有相同用户 ID 标识号的进程的打开文件。

如果同时定义了 HASSECURITYHASNOSOCKSECURITY,则任何用户都可以列出打开的套接字文件,前提是使用 -i 选项进行选择。

如果未定义 HASSECURITY,则任何用户都可以列出所有打开的文件。

通过 -h-? 选项呈现的帮助输出会显示 HASSECURITYHASNOSOCKSECURITY 定义的状态。

有关使用 HASSECURITYHASNOSOCKSECURITY 选项编译 lsof 的信息,请参阅 lsof 发行版的 00README 文件中的“安全”部分。

用户可读且用户可写的设备缓存文件的创建和使用由编译时 HASDCACHE 选项控制。请参阅“设备缓存文件”部分及其后面的部分,了解有关如何形成其路径的详细信息。从安全角度来看,重要的是要注意,在默认的 lsof 发行版中,如果执行 lsof 的实际用户 ID 是 root,则设备缓存文件将写入 root 的主目录(例如,//root)。当未定义 HASDCACHE 时,lsof 不会写入或尝试读取设备缓存文件。

当定义了 HASDCACHE 时,通过 -h-D?-? 选项呈现的 lsof 帮助输出将提供设备缓存文件处理信息。当未定义 HASDCACHE 时,-h-? 输出中将没有 -D 选项的描述。

在决定禁用设备缓存文件功能之前——启用它可以提高 lsof 的性能,因为可以减少检查 /dev(或 /devices)中所有节点时的启动开销——请阅读 lsof 发行版的 00DCACHE 文件和 lsof 常见问题解答中对此功能的讨论(常见问题解答部分会说明其位置)。

如有疑问,您可以使用 -Di 选项临时禁用设备缓存文件的使用。

lsof 用户使用 -k-m 选项声明替代的内核名称列表或内存文件时,lsof 会使用 access(2) 检查用户是否有权读取它们。这是为了防止 lsof 的模式可能赋予的任何特殊权限让它读取通常无法通过实际用户 ID 的权限访问的文件。

输出

本节描述了 lsof 为每个打开的文件列出的信息。有关可以由另一个程序处理的输出的更多信息,请参阅“其他程序的输出”部分。

^ sof 仅输出可打印的 8 位字符(通过 isprint(3) 声明)。非可打印字符以以下三种形式之一打印:C \``\[bfrnt]`` 形式;控制字符^形式(例如,^@);或十六进制形式,以\x开头(例如,\xab)。空格在“COMMAND”列中为不可打印字符(\x20`),而在其他地方是可打印的。

对于某些方言——如果方言的 machine.h 头文件中定义了 HASSETLOCALE——lsof 将打印语言区域的扩展 8 位字符。必须向 lsof 进程提供一个语言区域环境变量(例如,LANG),其值表示一个已知的语言区域,在该语言区域中,扩展字符被 isprint(3) 视为可打印字符。否则,lsof 会将扩展字符视为不可打印字符,并根据其用于不可打印字符的规则进行打印,如上所述。请参阅方言的 setlocale(3) 手册页,了解可以使用 LANG 替代的其他环境变量的名称——例如,LC_ALLLC_CTYPE 等。


如果 machine.h 头文件中定义了 HASSETLOCALEHASWIDECHAR,并且为 lsof 进程定义了合适的语言环境,则 lsof 的语言环境支持也涵盖宽字符——例如 UTF-8。在这种情况下,如果 iswprint(3) 函数报告这些宽字符是可打印的,则它们将被打印出来。

如果未定义 HASSETLOCALEHASWIDECHAR 或合适的语言环境,或者如果 iswprint(3) 函数报告的宽字符不可打印,则 lsof 会将这些宽字符视为不可打印字符,并根据其对不可打印字符的规则打印每个字符的 8 位。

有关更多信息,请参阅 lsof FAQ 中“语言环境支持”部分中的答案(FAQ 部分会给出其位置)。

^ sof 每次运行时都会动态调整输出列的大小,以保证每个列的最小尺寸。它还保证每个列与其前一个列之间至少有一个空格。

COMMAND 包含与该进程关联的 UNIX 命令名称的前九个字符。如果使用 +c w 选项指定了一个非零的 w 值,则该列包含与该进程关联的 UNIX 命令名称的前 w 个字符,但最多不能超过 UNIX 提供的字符数。(请参阅 +c w 命令的说明或 lsof FAQ,以获取更多信息。FAQ 部分会给出其位置。)

如果 `w` 小于列标题的长度(即“COMMAND”),则该值将被提高到该长度。

如果使用 `+c w` 选项指定了一个零值 `w`,则该列包含与该进程关联的 UNIX 命令名称的所有字符。

内核在其结构中维护的所有命令名称字符都将在指定命令名称描述符 (`c`) 时在字段输出中显示。有关选择字段输出和关联的命令名称描述符的信息,请参见“其他命令的输出”部分。

PID 是进程的进程 ID。

TID 是任务(线程)ID,如果该方言支持任务(线程)报告并且正在列出任务(线程)。(如果帮助输出——即 -h-? 选项的输出——显示此选项,则该方言支持任务(线程)报告。)

在 Linux 中,空白的 `TID` 列表示一个进程——即非任务。

TASKCMD 是任务命令名。通常,它与 COMMAND 列中进程的名称相同,但某些任务实现(例如 Linux)允许任务更改其命令名。

TASKCMD 列的宽度受与 COMMAND 列相同的尺寸限制。

ZONE 是 Solaris 10 及更高版本的区域名称。必须使用 -z 选项选择此列。

SECURITY-CONTEXT 是 SELinux 安全上下文。必须使用 -Z 选项选择此列。请注意,当在正在运行的 Linux 内核中禁用 SELinux 时,-Z 选项会被禁用。

PPID 是进程的父进程 ID。仅当指定了 -R 选项时才显示。

PGID 是与进程关联的进程组 ID。仅当指定了 -g 选项时才显示。

USER 是进程所属用户的用户 ID 编号或登录名,通常与 [ps]({filename}../../ps)(1) 报告的值相同。但是,在 Linux 上,USER 是在 /proc/<PID>/ 中 lsof 找到有关进程的信息的目录的所有者,即用户 ID 编号或登录名。通常,该值与 [ps]({filename}../../ps)(1) 报告的值相同,但当进程已更改其有效用户 ID 时,可能会有所不同。(有关何时显示用户 ID 编号或登录名,请参阅 -l 选项的说明。)

FD 是文件或以下内容的 File Descriptor 编号:

cwd 当前工作目录;

Lnn AIX 中的库引用; ctty 字符终端; DEL 已删除的文件; err FD 信息错误(请参阅 NAME 列); fp. Fileport(Darwin); jld jail 目录(FreeBSD); ltx 共享库文本(代码和数据); Mxx 十六进制内存映射类型编号 xx。 m86 DOS Merge 映射文件; mem 内存映射文件; mmap 内存映射设备; NOFD 对于无法打开的 Linux /proc//fd 目录,目录路径出现在 NAME 列中,后跟错误消息; pd 父目录; Rnn 未知的 pregion 编号(HP-UX); rtd 根目录; twd 每个任务的当前工作目录; txt 程序文本(代码和数据); v86 VP/ix 映射文件;

FD 后跟以下字符之一,描述文件以何种模式打开:

r 表示读访问;
w 表示写访问;
u 表示读写访问;
空格 表示模式未知且没有锁
字符 之后;
`-` 表示模式未知且有锁
字符 之后。

模式字符后跟以下锁字符之一,描述应用于文件的锁类型:

N 表示 SolarIS NFS 锁的未知类型;
r 表示文件部分上的读锁;
R 表示整个文件上的读锁;
w 表示文件部分上的写锁;
W 表示整个文件上的写锁;
u 表示任何长度的读写锁;
U 表示锁的未知类型;
x 表示 SCO OpenServer Xenix 锁在文件部分上;
X 表示 SCO OpenServer Xenix 锁在整个文件上;
空格 表示没有锁。

请参阅“LOCKS”部分,了解有关锁定信息字符的更多信息。

FD 列的内容构成一个字段,用于在后处理脚本中进行解析。 FD 数字大于 9999 时,将被缩写为“*”,后跟最后三个数字。例如,10001 显示为“*001”。

TYPE 是与文件关联的节点的类型,例如 VDIR、VREG 等。

或者“ax25”,表示 Linux AX.25 套接字;
或者“a_inode”,表示匿名 inode;
或者“icmp”,表示 ICMP 套接字;
或者“inet”,表示 Internet 域套接字;
或者“ipx”,表示 IPX 套接字;
或者“key”,表示内部密钥管理套接字;
或者“lla”,表示 HP-UX 链路级访问文件;
或者“ndrv”,表示网络驱动程序套接字;
或者“netlink”,表示 netlink 套接字;
或者“pack”,表示数据包套接字;
或者“ppp”,表示 PPP 套接字;
或者“raw”,表示原始套接字;
或者“raw6”,表示原始 IPv6 套接字;
或者“rte”,表示 AF_ROUTE 套接字;
或者“sock”,表示未知域的套接字;
或者“systm”,表示系统套接字;
或者“unix”,表示 UNIX 域套接字;
或者“x.25”,表示 HP-UX x.25 套接字;
或者“ATALK”,表示 AppleTalk 套接字;
或者“BLK”,表示块设备文件;
或者“CHR”,表示字符设备文件;
或者“DEL”,表示已删除的 Linux 映射文件;
或者“DIR”,表示目录;
或者“DOOR”,表示 VDOOR 文件;
或者“EVENTFD”,表示 eventfd;
或者“FIFO”,表示 FIFO 特殊文件;
或者“FSEVENTS”,表示 fsevents;
或者“IPv4”,表示 IPv4 套接字;
或者“IPv6”,表示打开的 IPv6 网络文件——即使其地址是 IPv4,但在 IPv6 地址中进行了映射;
或者“KQUEUE”,表示 BSD 风格的内核事件队列文件;
或者“LINK”,表示符号链接文件;
或者“MPB”,表示多路复用块文件;
或者“MPC”,表示多路复用字符文件;
或者“PAS”,表示 /proc/as 文件;
或者“PAXV”,表示 /proc/auxv 文件;
或者“PCRE”,表示 /proc/cred 文件;
或者“PCTL”,表示 /proc 控制文件;
或者“PCUR”,表示当前的 /proc 进程;
或者“PCWD”,表示 /proc 当前工作目录;
或者“PDIR”,表示 /proc 目录;
或者“PETY”,表示 /proc 可执行类型(etype);
或者“PFD”,表示 /proc 文件描述符;
或者“PFDR”,表示 /proc 文件描述符目录;
或者“PFIL”,表示可执行的 /proc 文件;
或者“PFPR”,表示 /proc FP 寄存器集;
或者“PGD”,表示 /proc/pagedata 文件;
或者“PGID”,表示 /proc 组通知文件;
或者“PIPE”,表示管道;
或者“PLC”,表示 /proc/lwpctl 文件;
或者“PLDR”,表示 /proc/lpw 目录;
或者“PLDT”,表示 /proc/ldt 文件;
或者“PLPI”,表示 /proc/lpsinfo 文件;
或者“PLST”,表示 /proc/lstatus 文件;
或者“PLU”,表示 /proc/lusage 文件;
或者“PLWG”,表示 /proc/gwindows 文件;
或者“PLWI”,表示 /proc/lwpsinfo 文件;
或者“PLWS”,表示 /proc/lwpstatus 文件;
或者“PLWU”,表示 /proc/lwpusage 文件;
或者“PLWX”,表示 /proc/xregs 文件;
或者“PMAP”,表示 /proc 映射文件(map);
或者“PMPS”,表示 /proc/maps 文件;
或者“PMEM”,表示 /proc 内存映像文件。

或者 ``PNTF'',表示 /proc 进程通知文件;

或者 ``POBJ'',表示 /proc/object 文件;

或者 ``PODR'',表示 /proc/object 目录;

或者 ``POLP'',表示旧格式的 /proc 轻量级进程文件;

或者 ``POPF'',表示旧格式的 /proc PID 文件;

或者 ``POPG'',表示旧格式的 /proc 页面数据文件;

或者 ``PORT'',表示 SYSV 命名管道;

或者 ``PREG'',表示 /proc 寄存器文件;

或者 ``PRMP'',表示 /proc/rmap 文件;

或者 ``PROCDSC'',表示处理器描述符;

或者 ``PRTD'',表示 /proc 根目录;

或者 ``PSGA'',表示 /proc/sigact 文件;

或者 ``PSIN'',表示 /proc/psinfo 文件;

或者 ``PSTA'',表示 /proc 状态文件;

或者 ``PSXMQ'',表示 POSIX 消息队列文件;

或者 ``PSXSEM'',表示 POSIX 信号量文件;

或者 ``PSXSHM'',表示 POSIX 共享内存文件;

或者 ``PTS'',表示 /dev/pts 文件;

或者 ``PUSG'',表示 /proc/usage 文件;

或者 ``PW'',表示 /proc/watch 文件;

或者 ``PXMP'',表示 /proc/xmap 文件;

或者 ``REG'',表示普通文件;

或者 ``SHM'',表示共享内存文件;

或者 ``SMT'',表示共享内存传输文件;

或者 ``STR'',表示流;

或者 ``STSO'',表示流套接字;

或者 ``UNKN'',表示未知文件;

或者 ``UNKNcwd'',表示未知当前工作目录;

或者 ``UNKNdel'',表示未知已删除文件;

或者 ``UNKNfd'',表示未知文件描述符;

或者 ``UNKNmem'',表示未知内存映射文件;

或者 ``UNKNrtd'',表示未知根目录;

或者 ``UNKNtxt'',表示未知程序文本;

或者 ``UNNM'',表示未命名类型文件;

或者 ``XNAM'',表示 OpenServer Xenix 未知类型的特殊文件;

或者 ``XSEM'',表示 OpenServer Xenix 信号量文件;

或者 ``XSD'',表示 OpenServer Xenix 共享数据文件;

或者 ``UNSP'',表示不受支持的文件;

或者如果相应名称未知,则使用四个类型编号字节。

FILE-ADDR 包含内核文件结构的地址,当指定了 +f 时;

FCT 包含内核文件结构中的文件引用计数,当指定了 +f 时;

FILE-FLAG 当指定了 +f 中的 g 或 G 时,此字段包含内核文件结构的 f_flag[s] 成员的内容以及内核的每个进程的打开文件标志(如果可用);'G' 将以十六进制显示它们;'g',作为简短名称;两个列表可以显示,条目之间用逗号分隔,列表之间用分号 (;) 分隔;第一个列表可以包含 f_flag[s] 值的简短名称,来自以下表格:

AIO       异步 I/O(例如,FAIO)
AP        追加
ASYN      异步 I/O(例如,FASYNC)
BAS       块、测试和设置正在使用
BKIU      如果正在使用则阻止
BL        使用块偏移量
BSK       块寻址
CA        复制避免
CIO       并发 I/O
CLON      克隆
CLRD      CL 读取
CR        创建
DF        延迟
DFI       延迟 IND
DFLU      数据刷新
DIR       直接
DLY       延迟
DOCL      执行克隆
DSYN      仅数据完整性
DTY       必须是一个目录
EVO       仅事件
EX        用于执行打开
EXCL      独占打开
FSYN      同步写入
GCDF      在 unp_gc() 期间延迟(AIX)
GCMK      在 unp_gc() 期间标记(AIX)
GTTY      通过 /dev/tty 访问
HUP       HUP 正在进行
KERN      内核
KIOC      内核发起的 ioctl
LCK       具有锁
LG        大文件
MBLK      流消息块
MK        标记
MNT       挂载
MSYN      多路复用同步
NATM      不要更新 atime
NB        非阻塞 I/O
NBDR      不要执行 BDRM 检查
NBIO      SYSV 非阻塞 I/O
NBF       n 缓冲生效
NC        不缓存
ND        无延迟
NDSY      无数据同步
NET       网络
NFLK      不要跟随链接
NMFS      NM 文件系统
NOTO      禁用后台停止
NSH       不共享
NTTY      没有控制 TTY
OLRM      OLR 镜像
PAIO      POSIX 异步 I/O
PATH      路径
PP        POSIX 管道
R         读取
RC        文件和记录锁缓存
REV       已撤销
RSH       共享读取
RSYN      读取同步
RW        读写访问
SL        共享锁
SNAP      已烹饪的快照
SOCK      套接字
SQSH      Sequent 在打开时设置共享集
SQSV      Sequent 在打开时设置 SVM 集
SQR       Sequent 在打开时设置修复集
SQS1      Sequent 完全共享打开
SQS2      Sequent 部分共享打开
STPI      停止 I/O
SWR       同步读取
SYN       写入时文件完整性
TCPM      避免 TCP 冲突
TMPF      临时文件
TR        截断
W         写入
WKUP      并行 I/O 同步
WTG      并行 I/O 同步
VH        vhangup 挂起
VTXT      虚拟文本
XL        独占锁

此名称列表是从方言头文件 `<fcntl.h>`、`<linux/fs.h>`、`<sys/fcntl.c>`、`<sys/fcntlcom.h>` 和 `<sys/file.h>` 中的 `F* #define` 派生而来;请参阅 `common.h` 头文件,其中包含一个列表,显示了上述简写名称与头文件定义之间的对应关系;

第二个列表(在分号之后)可能包含内核进程打开文件标志的简写名称,来自此表:

ALLC      已分配
BR        该文件已被读取
BHUP      活动已通过 SIGHUP 停止
BW        该文件已被写入
CLSG      正在关闭
CX        关闭时执行 (参见 `fcntl(F_SETFD)`)
LCK       已应用锁
MP        已进行内存映射
OPIP      正在打开 - 正在进行中
RSVW      保留等待
SHMT      UF_FSHMAT 已设置(AIX)
USE       正在使用(多线程)

NODE-ID(或对于某些方言,为 INODE-ADDR)包含文件节点的唯一标识符(通常是内核 vnode 或 inode 地址,但也偶尔是设备号和节点号的连接),当指定了 `n` 到 `+f` 时;

DEVICE 包含字符特殊文件、块特殊文件、常规文件、目录或 NFS 文件的设备号,用逗号分隔;

或者对于 Tru64 UNIX 中的内存文件系统节点,为“memory”;

或者 Solaris 套接字流的私有数据区域的地址;

或者一个内核引用地址,用于标识该文件(内核引用地址可用于 FIFO,例如);

或 Linux AX.25 套接字设备的基地址或设备名称。

通常,Tru64 UNIX 内核地址的较低 32 位才会被显示。

SIZE、SIZE/OFF 或 OFFSET
是文件的大小或文件中的字节偏移量。如果可用,则会在该列中显示一个值。lsof 会显示适当的值——大小或偏移量——具体取决于文件的类型和 lsof 的版本。

在某些 UNIX 变体中,lsof 无法从其内核数据源中获取准确或一致的文件偏移量信息,有时只是针对特定类型的文件(例如,套接字文件)。在其他情况下,文件没有固定的大小——例如,套接字、FIFO、管道——因此 lsof 会显示在其内核缓冲区描述符中找到的内容量(例如,套接字缓冲区大小计数或 TCP/IP 窗口大小)作为其大小。有关更多信息,请参阅 lsof FAQ(FAQ 部分给出了其位置)。

文件大小以十进制形式显示;偏移量通常以十进制形式显示,如果包含 8 位或更少数字,则以“0t”作为前缀;如果超过 8 位,则以十六进制形式显示,以“0x”作为前缀。(有关何时将 8 默认为其他值的信息,请参阅 -o o 选项的说明。)

因此,前导“0t”和“0x”标识了偏移量,当该列可以包含大小和偏移量时(即,其标题为 SIZE/OFF)。

如果指定了 -o 选项,lsof 始终会显示文件偏移量(如果没有文件偏移量,则不显示),并对该列进行标记为 OFFSET。偏移量始终以“0t”或“0x”开头,如上所述。

lsof 用户可以使用 -o o 选项来控制从“0t”到“0x”的切换。有关更多信息,请参阅其说明。

如果指定了 -s 选项,lsof 始终会显示文件大小(如果没有文件大小,则不显示),并对该列进行标记为 SIZE。-o 和 -s 选项是互斥的;它们不能同时指定。

如果指定了 -H 选项,lsof 以人类可读的形式显示文件大小。

对于没有固定大小的文件——例如,不驻留在磁盘设备上——lsof 将显示有关文件当前大小或位置的适当信息(如果可以在定义该文件的内核结构中找到)。

NLINK 包含文件链接计数(当指定了 +L 时);

NODE 是本地文件的节点号;

或 NFS 文件的服务器主机上的 inode 号;

或 Internet 协议类型——例如,“TCP”;

或“STR”,表示流;

或“CCITT”,表示 HP-UX x.25 套接字;

或 Linux AX.25 套接字设备的 IRQ 或 inode 号。

NAME 是安装点和文件系统名称,文件位于该文件系统上;

或是在 names 选项中指定的文件的名称(在解析任何符号链接之后);

或字符特殊设备或块特殊设备的名称;

或网络文件的本地和远程 Internet 地址;本地主机名称或 IP 号码后跟一个冒号 (':'),然后是端口,"->",然后是两部分的远程地址;IP 地址可以报告为数字或名称,具体取决于 +|-M、-n 和 -P 选项;冒号分隔的 IPv6 数字包含在方括号中;IPv4 INADDR_ANY 和 IPv6 IN6_IS_ADDR_UNSPECIFIED 地址以及零端口号表示为星号 ('*');UDP 目标地址后可以跟随着上次向该目标发送数据包的时间;TCP、UDP 和 UDPLITE 远程地址后可以跟随着 TCP/TPI 信息(状态——例如,“(ESTABLISHED)”,“(Unbound)”,队列大小和窗口大小——并非所有变体都支持),方式类似于 [netstat]({filename}../../netstat)(1) 所报告的内容;有关状态、队列大小和窗口大小的更多信息,请参阅 -T 选项的说明,或者查看 OUTPUT FOR OTHER PROGRAMS 中 TCP/TPI 字段的说明。

或 UNIX 域套接字的地址或名称,可能包括流克隆设备名称、文件系统对象的路径名、本地和远程内核地址、
套接字对信息以及绑定的 vnode 地址;

或 NFS 文件的本地和远程挂载点名称;

或“STR”,后跟流名称;

或流字符设备名称,后跟“->”,以及流名称或流模块名称列表,这些名称由“->”分隔;

或“STR:”,后跟 SCO OpenServer 流设备和模块名称,这些名称由“->”分隔;

或系统目录名称,“--”,以及 lsof 可以在内核名称缓存中找到的所选方言的路径名称的尽可能多的组件(有关更多信息,请参阅“内核名称缓存”部分);

或“PIPE->”,后跟 Solaris 内核管道目标地址;

或“COMMON:”,后跟 Solaris 通用 vnode 的 vnode 设备信息结构的设备名称;

或地址族,后跟一个斜杠 (/),后跟 14 个用逗号分隔的非 Internet 原生套接字地址的字节;

或 HP-UX x.25 本地地址,后跟虚拟连接号(如果存在),后跟远程地址(如果存在);

或“(dead)”,表示已分离的 Tru64 UNIX 文件 - 通常是已使用 TIOCNOTTY ioctl 标记并由守护程序关闭的终端文件;

或“rd=<offset>”和“wr=<offset>”,表示 FIFO 的读偏移量和写偏移量值;

或“clone n:/dev/event”,表示 SCO OpenServer 文件 /dev/event 设备的克隆,其中 n 是文件的次设备号;

或“(socketpair:n)”,表示 Solaris 2.6、8、9 或 10 UNIX 域套接字,由 socketpair(3N) 网络函数创建;

或“no PCB”,表示没有关联协议块的套接字文件,可选地后跟 `, CANTSENDMORE`,如果已禁用套接字上的发送,或者后跟 `, CANTRCVMORE`,如果已禁用套接字上的接收(例如,通过 [shutdown]({filename}../../shutdown)(2) 函数)。

或 Linux IPX 套接字文件的本地和远程地址,格式为 `<net>:[<node>:]<port>`,后跟括号中的发送和接收队列大小以及连接状态;

或者对于 UnixWare 7.1.1 及更高版本的内核 UNIX 域套接字,可以是“dgram”或“stream”,后跟一个冒号 (:) 和可用的本地路径名,然后是“->”和可用的远程路径名或十六进制内核套接字地址;

或者对于 Linux SCTP 套接字,可以是关联值、关联索引、端点值、本地地址、本地端口、远程地址和远程端口;

或者“protocol:”后跟 Linux 套接字的协议属性。

对于支持“namefs”文件系统的方言,允许使用 `fattach(3C)` 将一个文件附加到另一个文件,lsof 会在 NAME 列中添加“(FA:<address1><direction><address2>)”。`<address1>` 和 `<address2>` 是十六进制的 vnode 地址。`<direction>` 如果 `<address2>` 已通过 `fattach` 附加到地址为 `<address1>` 的此 vnode,则为“<-”;如果 `<address1>`,即此 vnode 的 vnode 地址,已 `fattach` 到 `<address2>`,则为“->”。如果 `<address1>` 已经在 DEVICE 列中出现,则可以省略 `<address1>`。

对于 Solaris 10 上的打开文件,lsof 可以在 NAME 列中添加两个带括号的注释:“(?)”如果 lsof 认为路径名可能不准确;以及“(deleted)”如果指定了 -X 选项并且 lsof 检测到打开文件的路径名已被删除。有关这些 NAME 列添加项的更多信息,请参阅 lsof FAQ(FAQ 部分给出了其位置)。

LOCKS

lsof 无法以单个字符的形式充分报告各种 UNIX 方言的文件锁。它在单个字符中报告的内容是在内核中找到的信息与报告格式的限制之间的权衡。

此外,当一个进程对文件持有多个字节级锁时,lsof 仅报告遇到的第一个锁的状态。如果它是字节级锁,则锁字符将以小写形式报告 - 即 rwx - 而不是报告为完全文件锁的相应大写形式。

通常,lsof 只能报告本地进程对本地文件持有的锁。当本地进程设置远程挂载(例如,NFS)文件的锁时,远程服务器主机通常会记录锁状态。一个例外是 Solaris - 在 2.3 的某些补丁级别以及所有高于 2.4 的版本中,Solaris 内核会在本地结构中记录远程锁的信息。

lsof 无法报告某些 UNIX 方言的锁。有关更多信息,请参阅本手册页面的 BUGS 部分或 lsof FAQ(FAQ 部分给出了其位置)。

OUTPUT FOR OTHER PROGRAMS

如果指定了 -F 选项,lsof 将生成适合由其他程序处理的输出 - 例如,awk 或 Perl 脚本,或 C 程序。

每个信息单元都输出到一个字段中,该字段以一个前导字符标识,并以 NL(012)结尾(或者如果指定了 0(零)字段标识符,则以 NUL(000)结尾)。字段的数据紧跟在字段标识符之后,并延伸到字段终止符。

可以将字段输出视为过程集和文件集。过程集以一个标识符为 p(表示进程 ID(PID))的字段开始。它延伸到下一个 PID 字段的开始或过程的第一个文件集的开始,以较早者为准。过程集中包含用于标识命令、进程组 ID(PGID)号、任务(线程)ID(TID)以及用户 ID(UID)号或登录名的字段。

文件集以一个标识符为 f(表示文件描述符)的字段开始。它后面跟着描述文件的访问模式、锁定状态、类型、设备、大小、偏移量、inode、协议、名称和流模块名称的行。它延伸到下一个文件或过程集的开始,以较早者为准。

当使用 0(零)字段标识符选择 NUL(000)字段终止符时,lsof 在每个过程集和文件集的末尾都以 NL(012)字符结尾。

Lsof 始终生成一个字段,即 PID(p)字段。在重复模式下,标记(m)也会生成。所有其他字段都可以通过在 -F 选项后面的字段标识符字符列表中选择性地声明。当字段选择字符标识一个 lsof 通常不列出的项目时——例如,使用 -R 选项选择 PPID——指定该字段字符(例如,-FR)也会选择该项目的列出。

Lsof 版本从 4.88 到 4.93.2 始终生成一个额外的字段,即文件描述符(f)字段。但是,此版本的 lsof 不再生成它。此更改是为了支持以下用例:用户只需要 PID 字段,而不需要文件描述符字段。如果需要该字段,请显式指定 f

完全有可能选择一组难以解析的字段——例如,如果未选择文件描述符字段,则可能难以标识文件集。为了帮助您避免这种困难,lsof 支持 -F 选项;它选择所有字段的输出,这些字段都以 NL 终止符结尾(-F0 选项对选择所有字段的输出,这些字段都以 NUL 终止符结尾)。出于兼容性原因,-F-F0 都不选择原始设备字段。

以下是 lsof 将生成的字段。首先列出的单个字符是字段标识符。

a    文件访问模式
c    进程命令名称(来自 proc 或用户结构的全部字符)
C    文件结构共享计数
d    文件的设备字符代码
D    文件的主要/次要设备编号(0x<十六进制>)
f    文件描述符
F    文件结构地址(0x<十六进制>)
G    文件标志(0x<十六进制>;如果后跟 +fg,则显示名称)
g    进程组 ID
i    文件的 inode 编号
K    任务 ID
k    链接计数
l    文件的锁定状态
L    进程登录名
m    重复输出之间的标记(始终在重复模式下选择)
M    任务命令名称
n    文件名、注释、Internet 地址
N    节点标识符(0x<十六进制>)
o    文件的偏移量(0t<十进制> 或 0x<十六进制>,请参阅 -o o)
p    进程 ID(始终选择)
P    协议名称
r    原始设备编号(0x<十六进制>)
R    父进程 ID
s    文件的大小(十进制)
S    文件的流标识符
t    文件的类型
T    TCP/TPI 信息,由前缀标识(`=` 是前缀的一部分):
    QR=<读取队列大小>
    QS=<发送队列大小>
    SO=<套接字选项和值>(并非所有方言)
    SS=<套接字状态>(并非所有方言)
    ST=<连接状态>
    TF=<TCP 标志和值>(并非所有方言)
    WR=<窗口读取大小>(并非所有方言)
    WW=<窗口写入大小>(并非所有方言)
    (TCP/TPI 信息并非所有受支持的 UNIX 方言都报告。-h 或 -? 帮助输出,用于 -T 选项,将显示可以请求哪些 TCP/TPI 报告。)
u    进程用户 ID
z    Solaris 10 及更高版本的区域名称
Z    SELinux 安全上下文(在禁用 SELinux 时被抑制)
0   使用 NUL 字段终止符字符代替 NL
19  特定于方言的字段标识符(-F? 的输出标识了可以在特定于方言的字段中找到的信息。)

可以通过指定 -F? 选项来获取有关这些字符及其描述的在线帮助信息。(根据您的 shell 要求转义 ? 字符。)可以在“输出”部分找到有关字段内容的更多信息。

例如,`\`\`-F pcfn\`\` 将选择进程 ID (`p`)、命令名称 (`c`)、文件描述符 (`f`) 和文件名 (`n`) 字段,并使用 NL 字段终止符。`\`\`-F pcfn0\`\` 选择相同的输出,但使用 NUL (000) 字段终止符。

lsof 并非为每个进程或文件集生成所有字段,而是仅生成可用的字段。某些字段是互斥的:文件设备字符和文件主/次设备号;文件 inode 编号和协议名称;文件名和流标识;文件大小和偏移量。这些互斥集中将出现其中一个成员,而不是全部成员。

通常,lsof 使用 NL (012) 字符作为每个字段的结尾。可以使用 0(零)字段标识符字符来更改字段终止符,使其为 NUL (000)。使用 NUL 终止符可能更容易与 xargs (1) 或其他引用机制难以处理字段输出中的字符范围的程序一起处理。当使用 NUL 字段终止符时,lsof 使用 NL (012) 字符来结束每个进程和文件集。

lsof 发行版中包含三个辅助工具,用于创建可以处理 lsof 字段输出的程序。第一个是 C 头文件 lsof_fields.h,其中包含字段标识符的符号、用于将其存储在表中的索引以及可以编译到程序中的说明字符串。lsof 使用此头文件。


第二个辅助工具是一组处理字段输出的示例脚本,使用 awk、Perl 4 和 Perl 5 编写。 它们位于 lsof 发行版的 scripts 子目录中。

第三个辅助工具是用于 lsof 测试套件的 C 库。 测试套件是用 C 编写的,并使用字段输出来验证 lsof 的正确操作。 该库可以在 lsof 发行版的 tests/LTlib.c 文件中找到。 该库使用第一个辅助工具,即 lsof_fields.h 头文件。

阻塞和超时

lsof 可能会被它使用的某些内核函数阻塞,例如 lstat(2)、readlink(2) 和 stat(2)。 当挂载 NFS 文件系统的宿主机变得不可访问时,这些函数会在内核中停止响应。

lsof 尝试使用计时器和子进程来打破这些阻塞,但这些技术并非完全可靠。 当 lsof 成功打破阻塞时,它会用错误消息报告。 可以使用 -t 和 -w 选项来抑制这些消息。

默认超时值可以通过 -h 或 -? 选项显示,并且可以通过 -S [t] 选项进行更改。 t 的最小值为两秒,但您应该避免使用较小的值,因为系统响应缓慢可能会导致短超时意外到期,并且可能会在 lsof 产生任何输出之前停止。

当 lsof 在访问挂载文件系统信息时必须打破阻塞时,它通常会继续执行,尽管显示的有关打开文件的信息会减少。

lsof 也可以通过指定 -O 选项来避免使用计时器和子进程来保护。 虽然这允许 lsof 以更少的开销启动,但它会使 lsof 完全暴露于可能导致它阻塞的内核情况中。 谨慎使用此选项。

避免内核阻塞

您可以使用 -b 选项告诉 lsof 避免使用会导致阻塞的内核函数。 这需要注意一些事项。

首先,使用此选项通常要求您的系统提供替代设备号,以替代 lsof 通常使用 lstat(2) 和 stat(2) 内核函数获得的设备号。 请参阅“替代设备号”部分,了解有关替代设备号的更多信息。

其次,您不能指定 lsof 要定位的文件名,除非它们是文件系统名称。 这是因为 lsof 需要知道在 lsof 选项中列出的文件的设备号和 inode 号,而 -b 选项会阻止 lsof 获取它们。 此外,由于 lsof 仅对具有替代项的文件系统拥有设备号,因此它定位文件系统上的文件的能力完全取决于替代项的可用性和准确性。 如果没有可用的替代项,或者它们不正确,则 lsof 将无法定位所命名文件系统上的文件。

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

最后,使用 -b 选项会导致 lsof 在需要使用该选项指示它避免使用的内核函数时发出警告消息。你可以通过指定 -w 选项来抑制这些消息,但如果你这样做,你将看不到警告消息中报告的替代设备编号。

替代设备编号

在某些平台上,当 lsof 无法通过 lstat(2)stat(2) 内核函数获取关于已挂载文件系统的信息,或者因为你指定了 -b 选项,lsof 可以从系统挂载表中获取一些它需要的信息——设备编号,并且可能包括文件系统类型。当这成为可能时,lsof 将报告它获得的设备编号。(你可以通过指定 -w 选项来抑制该报告。)

如果你的挂载表受 /etc/mtab/etc/mnttab 文件支持,并且包含一个选项字段,你可以通过为那些在其选项字符串中没有 dev=xxxx 字段的挂载点添加该字段来协助此过程。请注意:你必须能够编辑该文件——例如,某些挂载表(如最新的 Solaris /etc/mnttab 或 Linux /proc/mounts)是只读的,无法修改。

你还可以使用 +m+m m 选项来提供设备编号,前提是你的平台支持这些选项。检查 lsof-h-? 选项的输出,以查看 +m+m m 选项是否可用。

^ xxx 部分是文件系统设备编号的十六进制值。(请参考 lstat(2)stat(2) 函数输出的 st_dev 字段,以获取你的文件系统的适当值。)以下是 Sun Solaris 2.6 /etc/mnttab 中一个通过 NFS 远程挂载的文件系统的示例:

nfs  ignore,noquota,dev=2a40001

在你的挂载表文件中添加 dev=xxxx 条目具有优势,尤其是在从远程 NFS 服务器挂载的文件系统上。当远程服务器崩溃并且你想要通过在它的客户端上运行 lsof 来识别它的用户时,lsof 可能无法从 lstat(2)stat(2) 函数中获取该文件系统的输出。如果它可以从挂载表中获取文件系统的设备编号,它将能够显示在崩溃的 NFS 服务器上打开的文件。

一些不使用 ASCII 格式的 /etc/mtab/etc/mnttab 文件来存储挂载表的文件系统,可能仍然在其内部挂载表中提供替代设备编号。这包括 AIX、Apple Darwin、FreeBSD、NetBSD、OpenBSD 和 Tru64 UNIX。lsof 知道如何为这些平台获取替代设备编号,并在尝试 lstat(2)stat(2) 文件系统失败时使用它。


如果您不确定您的方言是否从其挂载表提供文件系统的替代设备号,请使用此 lsof 命令来查看它是否报告任何替代设备号:

lsof -b

查找以 ``假设 "dev=xxxx" 来自 ..." 开头的标准错误文件警告消息。

内核名称缓存

lsof 能够检查内核的名称缓存或使用其他内核功能(例如,Tru64 UNIX 下的 ADVFS x tag_to_path() 函数),在某些方言中,它可以用于大多数文件系统类型(不包括 AFS),并从中提取最近使用的路径名组件。 (AFS 文件系统的路径查找不使用内核的名称缓存;某些 Solaris VxFS 文件系统操作似乎也不使用它。)

lsof 在 NAME 列中报告它找到的完整路径。 如果 lsof 无法报告路径中的所有组件,则它会在 NAME 列中报告文件系统名称,后跟一个空格、两个 - 字符、另一个空格,以及它找到的路径组件,这些组件由 / 字符分隔。

当 lsof 以重复模式运行(即,指定了 -r 选项时),它能够报告相同文件的路径名组件的程度可能会因周期而异。 这是因为其他正在运行的进程可能会导致内核从其名称缓存中删除条目并用其他条目替换它们。

lsof 使用内核名称缓存来标识文件的路径,在某些情况下,这可能会导致它报告不正确的组件。 当内核名称缓存使用设备号和节点号作为键(例如,SCO OpenServer),并且快速更改的文件系统上的键被重用时,可能会发生这种情况。 如果 UNIX 方言的内核在文件被取消链接时不会清除名称缓存中的条目,则 lsof 可能会找到对缓存中错误条目的引用。 lsof FAQ(FAQ 部分给出了其位置。) 提供了有关此情况的更多信息。

lsof 可以报告以下方言的路径名组件:

FreeBSD
HP-UX
Linux
NetBSD
SCO OpenServer
SCO|Caldera UnixWare
Solaris
Tru64 UNIX

lsof 无法报告以下方言的路径名组件:

AIX

OpenBSD

如果您想知道为什么 lsof 无法报告某些方言的路径名组件,请参阅 lsof FAQ(FAQ 部分给出了其位置。)

设备缓存文件

检查 /dev(或 /devices)节点树中的所有成员,并使用 stat(2) 函数,这可能会消耗大量时间。 此外,lsof 所需的信息——设备号、inode 号和路径——很少会发生变化。

因此,lsof 通常会维护一个缓存的 /dev(或 /devices)信息的 ASCII 文本文件(例外:基于 /proc 的 Linux lsof,在这种情况下不需要)。 构建 lsof 的本地系统管理员可以控制设备缓存文件路径的形成方式,并从以下选项中进行选择:


通过 -D 选项指定的路径;
通过环境变量指定的路径;
系统范围的路径;
个人路径(默认);
个人路径,由环境变量修改。

请参阅 -h、-D?或 -?帮助选项的输出,以了解当前设备缓存支持的状态。帮助输出列出了当前 lsof 调用的默认只读模式设备缓存文件路径。-D?选项的输出列出了只读和写入设备缓存文件路径、任何适用的环境变量的名称以及个人设备缓存路径格式。

lsof 可以检测当前设备缓存文件是否被意外或恶意修改,方法包括计算并验证文件内容的 16 位循环冗余校验 (CRC) 总和。当 lsof 检测到文件出现问题时,它会发出警告并尝试删除当前缓存文件并创建一个新的副本,但仅写入进程可以合法写入的路径。

lsof 进程尝试读取设备缓存文件的路径可能与它可以合法写入的路径不同。因此,当 lsof 检测到需要更新设备缓存文件时,它可能会选择不同的路径来写入它,而不是从它读取了错误或过时版本的路径。

如果可用,-Dr 选项将禁止写入新的设备缓存文件。(在不带路径名参数的情况下指定时,它始终可用。)

当向系统添加新设备时,可能需要重新创建设备缓存文件。由于 lsof 将设备缓存文件的 mtime 与 /dev(或 /devices)目录的 mtime 和 ctime 进行比较,因此它通常会检测到已添加新设备;在这种情况下,lsof 会发出警告消息并尝试重建设备缓存文件。

每当 lsof 写入设备缓存文件时,它都会将其所有权设置为执行进程的实际 UID,并将其权限模式设置为 0600,从而限制其读取和写入文件的操作仅限于文件所有者。

影响设备缓存文件访问的 LSOF 权限

lsof 可执行文件的两个权限会影响其访问设备缓存文件的能力。这些权限由本地系统管理员在安装 lsof 时设置。

第一个也是较不常见的权限是 setuid-root。它在 lsof 运行时生效;其有效 UID 变为 root,而其实际(即已登录用户的)UID 不变。lsof 发行版建议为以下变体运行 setuid-root:

HP-UX 11.11 和 11.23
Linux

第二个也是更常见的权限是 setgid。它在 lsof 进程的有效组 ID(GID)设置为可以访问内核内存设备(例如,“kmem”、“sys”或“system”)时生效。


通常,具有 setgid 权限的 lsof 进程会在访问内核内存设备后放弃该权限。 在这种情况下,lsof 可以允许更宽松的设备缓存路径。 lsof 发行版建议,对于这些版本的操作系统,lsof 应该以 setgid 模式运行,并且允许它放弃 setgid 权限。

AIX 5.[12] 和 5.3-ML1
Apple Darwin 7.x Power Macintosh 系统
FreeBSD 4.x、4.1x、5.x 和 [6789].x,适用于基于 x86 的系统
FreeBSD 5.x、[6789].x 和 1[012].8,适用于 Alpha、AMD64 和 SPARC64
基于系统
HP-UX 11.00
NetBSD 1.[456]、2.x 和 3.x,适用于 Alpha、x86 和 SPARC 基于系统
OpenBSD 2.[89] 和 3.[0-9],适用于基于 x86 的系统
SCO OpenServer Release 5.0.6,适用于基于 x86 的系统
SCO|Caldera UnixWare 7.1.4,适用于基于 x86 的系统
Solaris 2.6、8、9 和 10
Tru64 UNIX 5.1

(注意:对于 AIX 5L 及更高版本,如果使用 -X 选项,则需要 lsof 以 setuid-root 权限运行。)

对于这些操作系统,lsof 不支持设备缓存,因此授予可执行文件的权限不适用于设备缓存文件。

Linux

通过 -D 选项指定的设备缓存文件路径

-D 选项提供了一种有限的方式来指定设备缓存文件路径。 它的 ? 函数将报告 lsof 将要使用的只读和可写设备缓存文件路径。

当 -D b、r 和 u 函数可用时,可以使用它们来请求构建特定位置的缓存文件 (b[路径]);读取但不重新构建 (r[路径]);或读取并重新构建 (u[路径])。 b、r 和 u 函数在某些条件下受到限制。 当 lsof 进程以 setuid-root 模式运行时,这些函数会受到限制。 与 r 函数一起指定的路径始终是只读的,即使它可用也是如此。

当 lsof 进程以 setgid 模式运行且 lsof 未放弃 setgid 权限时,b、r 和 u 函数也受到限制。(请参阅“影响设备缓存文件访问的 LSOF 权限”部分,以获取通常不放弃其 setgid 权限的实现列表。)

另一个 -D 函数是 i(表示“忽略”),它始终可用。

如果可用,b 函数告诉 lsof 使用 stat(2) 函数从内核读取设备信息,并在指定的路径上构建设备缓存文件。

如果可用,r 函数告诉 lsof 读取设备缓存文件,但不更新它。 当带有路径参数的 -Dr 一起使用时,它指定设备缓存文件路径。 当不带路径参数指定 r 函数时,r 函数始终可用。 如果 lsof 未以 setuid-root 模式运行并且放弃了其 setgid 权限,则路径参数可以与 r 函数一起使用。

如果可用,u 函数告诉 lsof 尝试读取并使用设备缓存文件。 如果它无法读取该文件,或者如果它发现该文件中的内容不正确或已过时,它将读取内核中的信息,并尝试写入更新版本的设备缓存文件,但仅写入 lsof 进程的有效和实际 UID 认为合法的路径。


从环境变量获取设备缓存路径

^ sof 的第二个选择是使用 LSOFDEVCACHE 环境变量的内容作为设备缓存文件。如果 lsof 进程以 setuid-root 方式运行,或者进程的实际 UID 是 root,则会避免使用此选项。

对从 LSOFDEVCACHE 环境变量获取的设备缓存文件路径,还有另一项限制:如果 lsof 进程没有放弃其 setgid 权限,则 lsof 不会将设备缓存文件写入该路径。(有关不放弃其 setgid 权限的实现,请参阅“影响设备缓存文 件访问的 LSOF 权限”部分。)

本地系统管理员可以在构建 lsof 时禁用 LSOFDEVCACHE 环境变量的使用,或者更改其名称。请查看 -D? 的输出,以获取环境变量的名称。

系统范围的设备缓存路径

本地系统管理员可以选择在构建 lsof 时使用系统范围的设备缓存文件。该文件通常由特殊的系统管理程序在系统启动或 /dev/devices 的内容发生更改时构建。如果已定义,则它是 lsof 的第三个设备缓存文件路径选择。

可以通过查看 lsof 的帮助选项输出(即,来自 -h-? 选项的输出)来确定本地安装是否使用了系统范围的设备缓存文件。

^ sof 默认情况下不会写入系统范围的设备缓存文件路径。必须使用 -D 函数在 root 用户拥有的程序中显式指定。一旦文件被写入,该程序必须将其权限模式更改为 0644(所有者可读和可写,组可读,其他用户可读)。

个人设备缓存路径(默认)

lsof 分发的默认设备缓存文件路径记录在执行 lsof 的实际 UID 的主目录中。 在主目录中添加第二个路径组件,形式为 .lsof_hostname。

这是 lsof 的第四个设备缓存文件路径选择,通常也是默认选择。 如果在构建 lsof 时定义了系统范围的设备缓存文件路径,并且 lsof 找不到系统范围的设备缓存文件时,将应用此第四个选择。 这是 lsof 在读取设备缓存文件时使用两个路径的唯一时间。

hostname 部分是执行主机的基本名称,由 gethostname(2) 返回。 基本名称定义为 gethostname(2) 输出中第一个 . 之前的字符,或者如果它不包含 .,则为整个 gethostname(2) 输出。

设备缓存文件属于用户 ID,并且仅由用户 ID 可读和可写,即其模式为 0600。 在给定主机上执行 lsof 的每个不同的实际用户 ID 都有一个不同的设备缓存文件。 路径中的 hostname 部分用于将写入到 NFS 挂载的主目录中的设备缓存文件与其他来自不同主机的设备缓存文件区分开。


通过此方法形成的个人设备缓存文件路径表示 lsof 将尝试读取的设备缓存文件,并且如果该文件不存在或其内容不正确或已过时,lsof 将尝试写入该文件。

不带路径名参数的 -Dr 选项将禁止写入新的设备缓存文件。

-D? 选项将列出用于构造个人设备缓存文件的格式规范。格式规范中使用的转换在 lsof 发行版的 00DCACHE 文件中描述。

修改后的个人设备缓存路径

如果本地系统管理员在构建 lsof 时定义了此选项,则 LSOFPERSDCPATH 环境变量的内容可用于添加个人设备缓存文件路径的组件。

LSOFPERSDCPATH 变量的内容将插入路径中,插入位置由本地系统管理员使用方言的 machine.h 头文件中 HASPERSDC 格式规范中的“%p”转换标记。(它放置在默认 lsof 发行版的家目录之后。)

因此,例如,如果 LSOFPERSDCPATH 包含“LSOF”,家目录是“/Homes/abe”,主机名是“lsof.itap.purdue.edu”,并且 HASPERSDC 格式是默认格式(“%h/%p.lsof_%L”),则修改后的个人设备缓存文件路径是:

/Homes/abe/LSOF/.lsof_vic

当 lsof 进程为 setuid-root 时,或者进程的实际 UID 为 root 时,将忽略 LSOFPERSDCPATH 环境变量。

如果 lsof 进程不放弃 setgid 权限,则 lsof 不会将内容写入修改后的个人设备缓存文件路径。(有关通常不放弃其 setgid 权限的实现列表,请参阅“影响设备缓存文件访问的 LSOF 权限”部分。)

例如,如果您想使用 LSOFPERSDCPATH 环境变量命名一个个人设备缓存文件路径的子目录,并且 lsof 不放弃其 setgid 权限,则您必须允许 lsof 在标准个人路径处创建设备缓存文件,然后使用 shell 命令将其移动到您的子目录中。

本地系统管理员可以:在构建 lsof 时禁用此选项;将环境变量的名称从 LSOFPERSDCPATH 更改为其他名称;更改 HASPERSDC 格式,以便在其他位置包含个人路径组件;或完全排除个人路径组件。请查阅 -D? 选项的输出,以获取环境变量的名称和 HASPERSDC 格式规范。

诊断

错误通过标准错误文件中的消息进行标识。

如果检测到任何错误,包括无法找到命令名称、文件名、Internet 地址或文件、登录名称、NFS 文件、PID、PGID 或 UID(这些都是 lsof 尝试列出的内容),lsof 将返回 1。如果指定了 -V 选项,lsof 将指示它未能列出的搜索项。如果指定了 -Q 选项,lsof 将忽略任何搜索项失败,并且仅在发生异常且无法恢复的情况时才返回错误。

如果未检测到任何错误,或者如果指定了 -Q 选项,或者 lsof 能够列出所有指定搜索参数的信息,则返回零 (0)。

当 lsof 无法打开对 /dev(或 /devices)或其子目录的访问权限,或者无法使用 stat(2) 获取有关其中文件的信息时,它会发出警告消息并继续。lsof 将会发出有关 /dev(或 /devices)中不可访问文件的警告消息,这在它的帮助输出中(通过 -h 或 >B -? 选项请求)以以下消息指示:

已启用不可访问的 /dev 警告。

可以使用 -w 选项来抑制警告消息。它也可能已由系统管理员在编译 lsof 时通过设置 WARNDEVACCESS 定义来抑制。在这种情况下,帮助输出将包含以下消息:

已禁用不可访问的 /dev 警告。

不可访问的设备警告消息通常会在 lsof 创建一个可用的设备缓存文件后消失。

示例

有关更全面的示例集,请参阅 lsof 分发版的 00QUICKSTART 文件。

要列出所有打开的文件,请使用:

lsof

要列出所有打开的 Internet、x.25(HP-UX)和 UNIX 域文件,请使用:

lsof -i -U

要列出所有打开的 IPv4 网络文件,这些文件由 PID 为 1234 的进程使用,请使用:

lsof -i 4 -a -p 1234

如果 PID 1234 不存在,或者 PID 1234 没有任何打开的 IPv4 网络文件,则可以添加 -Q:

lsof -Q -i 4 -a -p 1234

假设 UNIX 变体支持 IPv6,要仅列出所有打开的 IPv6 网络文件,请使用:

lsof -i 6

要列出所有使用主机 wonderland.cc.purdue.edu 的端口 513、514 或 515 上任何协议的文件,请使用:

lsof -i @wonderland.cc.purdue.edu:513-515

要列出所有使用 mace.cc.purdue.edu(cc.purdue.edu 是默认域)的任何端口上任何协议的文件,请使用:

lsof -i @mace

要列出所有打开的文件,这些文件属于登录名 ``abe`, 或用户 ID 1234,或进程 456,或进程 123,或进程 789,请使用:

lsof -p 456,123,789 -u 1234,abe

要列出设备 /dev/hd4 上的所有打开的文件,请使用:

lsof /dev/hd4

要查找具有打开的 /u/abe/foo 文件的进程,而无需担心没有这样的文件,请使用:

lsof -Q /u/abe/foo

要仅当进程具有打开的 /u/abe/foo 文件时才执行操作,请使用:

lsof /u/abe/foo  echo "still in use"

要向具有打开的 /u/abe/bar 文件的进程发送 SIGHUP 信号,请使用:

kill -HUP `lsof -t /u/abe/bar`

要查找任何打开的文件,包括打开的 UNIX 域套接字文件,其名称为 /dev/log,请使用:

lsof /dev/log

要查找具有在不可访问的服务器上的 NFS 文件系统 /nfs/mount/point 上的打开文件的进程,并且假设你的挂载表提供了 /nfs/mount/point 的设备编号,请使用:


lsof -b /nfs/mount/point

要执行上述搜索并抑制警告消息,请使用:

lsof -bw /nfs/mount/point

要忽略设备缓存文件,请使用:

lsof -Di

要为每个文件获取每个进程的文件描述符、文件设备编号和文件 inode 编号,以及 PID 和命令名称字段的输出,请使用:

lsof -FpcfDi

要列出运行 lsof 命令的每个进程的描述符 1 和 3 处的文件,登录 ID 为 abe,每 10 秒一次,请使用:

lsof -c lsof -a -d 1 -d 3 -u abe -r10

要列出当前工作目录,进程运行的命令恰好为四个字符长,并且第三个字符为“o”或“O”,请使用 -c 选项的这种正则表达式形式:

lsof -c /^..o.$/i -a -d cwd

要通过与其关联的数字点格式地址查找 IPv4 套接字文件,请使用:

lsof [email protected]

要通过与其关联的数字冒号格式地址查找 IPv6 套接字文件(当 UNIX 变体支持 IPv6 时),请使用:

lsof -i@[0:1:2:3:4:5:6:7]

要通过与其关联的数字冒号格式地址查找 IPv6 套接字文件(当 UNIX 变体支持 IPv6 时),该地址包含一串零(例如,环回地址),请使用:

lsof -i@[::1]

要获取包含当前时间的重复模式标记行,请使用:

lsof -rm====%T====

要向之前的标记行添加空格,请使用:

lsof -r "m==== %T ===="

错误

由于 lsof 在搜索打开的文件时读取内核内存,因此内核内存中的快速更改可能会产生不可预测的结果。

当文件具有多个记录锁时,锁状态字符(位于文件描述符之后)是从第一个锁结构的测试中派生的,而不是从可以由多个锁结构描述的单个记录锁的组合中派生。

除非 lsof 以 root set-UID 权限安装,否则它无法按名称搜索具有限制性访问权限的文件。否则,它仅限于搜索其用户或其 set-GID 组(如果存在)具有访问权限的文件。

原始套接字的destination地址的显示(例如,用于 ping)取决于 UNIX 操作系统。某些变体将其destination地址存储在原始套接字的协议控制块中,而其他变体则不存储。

^ sof 无法始终以与 ls(1) 相同的方式表示 Solaris 设备编号。例如,lstat(2)stat(2) 函数为 CD-ROM 文件挂载的目录(通常为 /cdrom)报告的主要和次要设备编号,与它为 CD-ROM 文件挂载的设备(通常为 /dev/sr0)报告的编号不同。(lsof 报告目录编号。)

对 /proc 文件系统的支持仅适用于 BSD 和 Tru64 UNIX 变体、Linux 以及源自 SYSV R4 的变体——例如,FreeBSD、NetBSD、OpenBSD、Solaris、UnixWare。

某些 /proc 文件项——设备编号、inode 编号和文件大小——在某些变体中不可用。在 /proc 文件系统中搜索文件可能需要指定完整的文件名。


在 Linux 进程中,不显示任何文本 (txt) 文件描述符。所有非当前工作目录、根目录和数值文件描述符的条目都标记为内存描述符。

Lsof 无法通过名称搜索 Tru64 UNIX 命名管道,因为它们的内核 lstat(2) 实现返回了错误的命名管道设备编号。

由于无法访问内核数据或内核数据中的错误,Lsof 无法完全或正确地报告 HP-UX 9.01、10.20 和 11.00 的锁。有关详细信息,请参阅 lsof FAQ(FAQ 部分给出了其位置)。

AIX SMT 文件类型是一种捏造。它是为文件结构创建的,这些文件结构的类型 (15) 在 AIX /usr/include/sys/file.h 头文件中未定义。创建此类文件结构的一种方法是使用 DISPLAY 变量设置为 :0.0 运行 X 客户端。

在基于 /proc 的 Linux lsof 中,不支持 +/-f[cfn] 选项,因为它不会从内核内存中读取内核结构。

环境

Lsof 可以访问以下环境变量。

LANG 定义了一种语言区域。请参阅 `setlocale(3)`,了解可以使用哪些其他变量来代替 `LANG`,例如 `LC_ALL`、`LC_TYPE` 等。

LSOFDEVCACHE 定义设备缓存文件的路径。有关更多信息,请参阅“来自环境变量的设备缓存路径”部分。

LSOFPERSDCPATH 定义修改后的个人设备缓存文件路径的中间组件。有关更多信息,请参阅“修改后的个人设备缓存路径”部分。

常见问题解答

常见问题及其答案(FAQ)可在 lsof 发行版的 00FAQ 文件中找到。

该文件的最新版本位于:

https://github.com/lsof-org/lsof/blob/master/00FAQ

文件

/dev/kmem 内核虚拟内存设备

/dev/mem 物理内存设备

/dev/swap 系统分页设备

.lsof_hostname lsof 的设备缓存文件(后缀是主机名,它是 `gethostname(2)` 返回的主机名的第一个组件)。

作者

Lsof 由 Purdue 普渡大学的 Victor A. Abell 编写。自 4.93.0 版本以来,GitHub 上的 lsof-org 团队维护 lsof。许多其他人也为 lsof 贡献了力量。他们在 lsof 发行版的 00CREDITS 文件中列出。

分发

lsof 的最新版本可在以下位置获得:

https://github.com/lsof-org/lsof/releases

参见

以下并非所有手册页都存在于 lsof 已移植到的每个 UNIX 变体中。

access(2), awk(1), crash(1), fattach(3C), ff(1), fstat(8), fuser(1), gethostname(2), isprint(3), kill(1), localtime(3), lstat(2), modload(8), mount(8), netstat(1), ofiles(8L), open(2), perl(1), ps(1), readlink(2), setlocale(3), stat(2), strftime(3), time(2), uname(1).