深入探索 Linux 的 lsof 命令
在 Linux 系统中,了解哪些文件被哪些进程打开对于系统管理和问题诊断是极其重要的。这正是lsof
命令,即 List Open Files,发挥其强大功能的场景。本文旨在详细介绍lsof
的起源、底层原理、参数意义,常见用法,并详解其返回结果的每个字段含义。此外,我们将讨论在使用lsof
命令时需要注意的事项。
1. lsof 的起源与演变 🌟
lsof
最初由 Victor A. Abell 在 1987 年开发,目的是为了帮助 Unix 系统的管理员和开发人员更好地监控和诊断系统问题。随着时间的推移,lsof
已经成为 Linux 系统中不可或缺的诊断工具。
2. 底层原理 🔍
lsof
通过访问 Linux 的/proc
文件系统来获取信息。/proc
文件系统包含了系统运行中的进程详情,包括但不限于打开的文件、网络连接等。lsof
解析这些信息,并以用户友好的格式呈现。
3. 参数详解 📚
-d <描述符>
:显示指定文件描述符的文件。-u <用户>
:显示特定用户打开的文件。-c <命令>
:显示由特定命令打开的文件。-p <PID>
:显示特定进程打开的文件。-i
:显示所有网络连接。-n
:直接显示 IP 地址,不进行域名解析,以加快处理速度。-l
:显示登录用户名称而非 ID。+D <目录>
:显示特定目录下打开的文件。-a
:用于多个条件的租户
4. 常见用法示例 🛠
4.1. 查看所有网络连接
命令:lsof -i
举例如下:
4.2. 查看特定用户打开的文件
命令:lsof -u <username>
举例如下:
4.3. 列出某个程序打开的文件
命令:lsof -c <app-name>
举例如下:
4.4. 查看指定进程打开的文件
命令:lsof -p <pid>
举例如下:
4.5. 查找监听特定端口的进程
命令:lsof -i :<port>
举例如下:
4.6. 查看所有处于监听状态的 TCP 连接
命令:lsof -i -sTCP:LISTEN
举例如下:
4.7. 查看所有处于建立好连接的 TCP
命令:lsof -i -sTCP:ESTABLISHED
举例如下:
4.8. 查看指定进程监听的端口
命令:lsof -i -a -p <port>
举例如下:
4.9. 查看指定命令监听的端口
命令:lsof -i -a -c <command>
举例如下:
4.10. 查看所有 TCP 连接
命令:lsof -i tcp
举例如下:
4.11. 查看所有 UDP 连接
命令:lsof -i udp
举例如下:
4.12. 查找使用特定文件的进程
命令:lsof <file>
举例如下:
4.13. 查找使用特定目录的进程
命令:lsof +D <dir>
举例如下:
5. 解读 lsof 的输出 📖
COMMAND:打开文件的进程名,通常是启动进程的命令名。
PID:每个运行中的进程在系统中都有一个唯一的标识符,即 PID
USER:进程所有者的用户名。
FD:文件描述符,唯一标识打开的文件。
TYPE:文件类型(如:DIR, REG)。
DEVICE:显示文件所在的设备编号,可能是以“主设备号,次设备号”的方式,譬如
255,0
SIZE/OFF:文件的大小或偏移量。
对于常规文件,显示文件的大小。
对于某些特殊文件,这可能是偏移量。
NODE:文件的 inode 号码。
NAME:文件名或网络连接的详细信息。
5.1. FD(文件描述符)
文件描述符是一个非负整数,它是 UNIX 和类 UNIX 操作系统(如 Linux)用来访问文件或输入/输出资源的抽象标识。在lsof
的输出中,FD
列显示了被进程打开的文件的文件描述符,它可以有以下几种形式:
数字:如
0
、1
、2
分别代表标准输入(STDIN)、标准输出(STDOUT)、标准错误输出(STDERR)。cwd
:代表当前工作目录。rtd
:代表根目录。txt
:表示程序代码。mem
:表示内存映射文件。数字 w:数字后跟
w
,如1w
,表示文件是以写入模式打开的。数字 u:数字后跟
u
,如2u
,表示文件是以读写模式打开的。数字 r:数字后跟
r
,表示文件是以只读模式打开的。
5.2. TYPE(文件类型)
TYPE
列提供了有关打开文件的类型信息,这可以帮助你了解文件是如何被使用的。TYPE
列的值可能包括但不限于:
REG
:常规文件。表示普通的数据文件。DIR
:目录。CHR
:字符设备文件,如终端、打印机等。BLK
:块设备文件,如硬盘、光驱等。FIFO
:命名管道,用于进程间通信。SOCK
:Socket 文件,用于网络通信。IPv4
和IPv6
:分别表示 IPv4 和 IPv6 的网络文件。unix
:表示 Unix 域 Socket 文件。
在lsof
命令的输出结果中,NAME
列是非常重要的一部分,它提供了被打开文件的名称或网络连接的详细信息。根据打开的资源类型,NAME
列的内容会有所不同。以下是NAME
列可能包含的信息类型及其含义的详细解释:
5.3. NAME
在 lsof 命令的输出结果中,NAME 列是非常重要的一部分,它提供了被打开文件的名称或网络连接的详细信息。根据打开的资源类型,NAME 列的内容会有所不同。以下是 NAME 列可能包含的信息类型及其含义的详细解释:
5.3.1. 文件系统中的文件
普通文件和目录:对于普通文件和目录,
NAME
列显示的是文件或目录的完整路径,如/home/user/document.txt
或/etc
。
5.3.2. 特殊文件
设备文件:如果是字符设备或块设备文件,
NAME
列会显示设备的文件路径,如/dev/tty
(终端设备)或/dev/sda1
(硬盘分区)。管道(Pipe):命名管道通常显示为
pipe:[inode]
,其中[inode]
是管道文件的 inode 编号。Socket:Socket 文件会显示协议类型和网络连接的详细信息。例如,
TCP
、UDP
连接会显示本地和远程的地址及端口号,格式类似于[local address]:[local port]->[remote address]:[remote port]
(对于 TCP)或[local address]:[local port]
(对于 UDP)。Unix 域 Socket 则显示为[类型]:[inode]
,类型通常是STREAM
、DGRAM
等。
5.3.3. 网络连接
IPv4/IPv6 连接:对于网络 Socket,
NAME
列提供了连接的详细信息,包括协议类型(如 TCP 或 UDP)、本地地址和端口号、远程地址和端口号(如果可用),以及连接的状态(如 LISTEN、ESTABLISHED)。格式示例:TCP localhost:ssh->192.168.1.5:53722 (ESTABLISHED)
。
5.3.4. 内存映射文件
内存映射区域:如果文件被映射到进程的内存空间(如共享库或执行文件的代码段),
NAME
列通常会显示文件的路径。对于匿名映射(不直接关联到文件系统中的文件),可能显示为[ anon ]
或特定的标记(如[ stack ]
表示进程的栈空间)。
5.3.5. 示例
让我们通过一些示例来进一步理解NAME
列的含义:
/usr/lib/x86_64-linux-gnu/libc-2.31.so
:表示libc
库文件被打开。TCP 127.0.0.1:4567->127.0.0.1:80 (ESTABLISHED)
:表示有一个 TCP 连接从本地的 4567 端口连接到本地的 80 端口,并且该连接已经建立。pipe:[45678]
:表示一个命名管道被打开,其 inode 编号为 45678。anon_inode:[eventfd]
:表示一个匿名 inode 关联的特殊文件被打开,通常用于事件通知。
理解lsof
输出中的NAME
列对于诊断系统问题、监控资源使用情况和性能优化非常有帮助。它提供了关于文件和网络资源使用情况的直观视图,帮助你快速定位问题。
5.4. 示例
让我们通过一个具体的lsof
命令执行结果的例子,来深入理解每一列的含义以及每行代表的信息。这里假设我们执行了一个列出特定进程打开的文件的lsof
命令。
解释如下:
第一行(
sshd
进程的当前工作目录)COMMAND
:sshd
,表示执行此操作的进程是 SSH 守护进程。PID
:1234
,进程 ID。USER
:root
,表示运行此进程的用户是 root。FD
:cwd
,表示当前工作目录。TYPE
:DIR
,指示打开的是一个目录。DEVICE
:253,0
,表示设备号。SIZE/OFF
:4096
,目录的大小。NODE
:2
,文件系统中的 inode 编号。NAME
:/
,当前工作目录的路径,根目录。第二行(
sshd
进程的可执行文件)COMMAND
: 同上,sshd
。PID
,USER
,DEVICE
: 同上。FD
:txt
,表示此文件是程序的文本(代码和数据)。TYPE
:REG
,常规文件。SIZE/OFF
:881736
,文件大小。NODE
:201
,文件的 inode 编号。NAME
:/usr/sbin/sshd
,sshd
守护进程的可执行文件路径。第三行(
sshd
进程监听的 Socket)COMMAND
: 同上。PID
,USER
: 同上。FD
:0u
,数字表示文件描述符,u
表示以读写模式打开。TYPE
:IPv4
,表示这是一个 IPv4 网络连接。DEVICE
:28991
,Socket 的内部标识。SIZE/OFF
:0t0
,对于 Socket 而言,此列通常不适用。NODE
: 不适用于网络连接。NAME
:*:ssh (LISTEN)
,表示这个进程正在所有接口的 22 端口(SSH)上监听入站连接。
6. 使用 lsof 的注意事项 🚨
权限:运行
lsof
可能需要超级用户权限,特别是当你尝试查看其他用户进程打开的文件时。性能:
lsof
可能需要一些时间来生成报告,特别是在系统打开了大量文件的情况下。使用-n
和-P
参数可以减少 DNS 和服务名解析的开销,加快命令执行速度。输出过滤:
lsof
的输出可能非常庞大,可以使用管道(|
)和grep
来过滤感兴趣的信息。安全性:在多用户环境中使用
lsof
时要注意隐私和安全性,不要泄露敏感信息。
7. 总结 🌈
lsof
是 Linux 系统管理员和开发人员手中的一把利剑,帮助他们诊断问题、监控系统状态。掌握lsof
的使用方法和它的参数对于深入理解系统的运行机制至关重要。通过实际的命令使用实例和对输出的解读,我们可以更好地管理系统资源,优化应用性能,甚至在复杂的故障排除过程中找到问题的根源。
lsof
不仅仅是一个单一的工具,它是一个功能强大的工具箱,通过其提供的丰富参数和选项,几乎可以洞察 Linux 操作系统中所有与文件相关的活动。无论是简单地查看哪个进程占用了某个端口,还是深入分析系统中的网络连接和文件使用情况,lsof
都能提供必要的帮助。
版权声明: 本文为 InfoQ 作者【GousterCloud】的原创文章。
原文链接:【http://xie.infoq.cn/article/4c2120ddd3d3409e6ce0a6ec1】。文章转载请联系作者。
评论