lsof 文件诊断工具

lsof(List Open Files)是 Linux 下用于列出当前系统打开文件的工具。在 Linux 中,“一切皆文件”——普通文件、目录、网络套接字、管道、设备等都被视为文件,因此 lsof 是系统诊断的利器。

常用命令速查

用途命令辅助记忆
查找已删除但仍被进程持有的文件lsof +L1 /挂载点+LN 代表 link count < N,此处为link count < 1,即link count = 0 即已被删除但仍被进程占用
全局搜索已删除的文件lsof -nP | grep '(deleted)'
查看某端口被哪个进程占用lsof -i :端口号
查看所有网络连接lsof -i
查看某用户打开的文件lsof -u 用户名
查看某进程打开的文件lsof -p PID
查看某命令打开的文件lsof -c 命令名
递归查看目录下被打开的文件lsof +D /路径
查看某文件被哪些进程打开lsof /path/to/file

常见用法详解

1. 查找已删除但仍被进程持有的文件

这是排查磁盘空间不释放问题的核心用法:

# 查看挂载点下所有 link count = 0 的文件
lsof +L1 /挂载点路径
 
# 全局搜索所有已删除的文件
lsof -nP | grep '(deleted)'

+L1 表示筛选 link count < 1 的文件,即已被删除但仍有进程持有句柄的文件。

2. 网络诊断:查看端口占用

# 查看 8080 端口被哪个进程占用
lsof -i :8080
 
# 查看所有 TCP 监听端口
lsof -iTCP -sTCP:LISTEN
 
# 查看所有 UDP 连接
lsof -iUDP

3. 按进程筛选

# 查看 PID 为 12345 的进程打开的所有文件
lsof -p 12345
 
# 查看某个命令(如 nginx)打开的文件
lsof -c nginx
 
# 组合:查看 nginx 进程的网络连接
lsof -c nginx -i

4. 按用户筛选

# 查看某个用户打开的所有文件
lsof -u root
 
# 排除某个用户
lsof -u ^root

5. 按文件/目录筛选

# 查看某个文件被哪些进程打开
lsof /var/log/syslog
 
# 递归查看某个目录下被打开的文件
lsof +D /var/log

6. 查看特定类型的文件

# 查看所有打开的正则文件(REG)
lsof -a -d 0-999 -c bash
 
# 查看所有 IPv4 网络连接
lsof -i4
 
# 查看所有 IPv6 网络连接
lsof -i6

输出解读

COMMAND   PID   USER   FD   TYPE  DEVICE   SIZE   NODE   NAME
dmserver 12345 dmdba   11w   REG   dm-0    100G  654321 /path/to/file.log (deleted)
字段含义
COMMAND进程名称(如 dmservernginx
PID进程 ID
USER运行进程的用户
FD文件描述符编号和模式(w 写、r 读、u 读写)
TYPE文件类型(REG 普通文件、DIR 目录、IPv4 网络等)
DEVICE设备编号
SIZE文件大小(若已删除则显示仍占用的空间)
NODEinode 节点号
NAME文件路径(后跟 (deleted) 表示已删除)

常用参数说明

参数说明
-n禁止 DNS 反向解析(加快速度)
-P禁止端口号到服务名的转换(加快速度)
-i显示网络连接
-u按用户筛选
-p按 PID 筛选
-c按命令名筛选
+D递归搜索目录
+L1显示 link count < 1 的文件(已删除)
-aAND 组合多个条件(默认是 OR)

无 lsof 时的备用方案:/proc 文件系统

当系统中未安装 lsof 时,可通过 /proc 文件系统达到类似效果:

# 查看所有进程的文件描述符,筛选标记为 (deleted) 的项
ls -la /proc/*/fd/ 2>/dev/null | grep '(deleted)'
 
# 查看某进程的所有打开文件描述符
ls -la /proc/PID/fd/
 
# 查看某进程打开的某个文件内容(即使文件已被删除,只要句柄存在即可读取)
cat /proc/PID/fd/文件描述符编号

/proc 的妙用

即使文件已被删除,通过 /proc/PID/fd/FD 仍可读取文件内容,这在恢复日志等场景中非常有用。

相关笔记