lsof如何揭示Linux一切皆文件的终极真相
lsof如何揭示Linux一切皆文件的终极真相
ZhangCurrylsof如何揭示Linux一切皆文件的终极真相
在 Linux 世界里,有一句几乎被奉为真理的话:
一切皆文件(Everything is a file)
但很多工程师只是在概念层面理解它。
直到你真正用好一个工具 —— lsof(List Open Files),你才会意识到:
它不是一句哲学,而是一个可以被“观测”的系统事实。
这篇文章,我们彻底讲清:
- lsof 的底层原理
- 它如何印证“一切皆文件”
- 生产环境 15+ 高价值使用场景
- 和 netstat / ss / ps 的区别
- 排查线上问题的完整思维模型
一、什么是 lsof?
lsof 是一个 Unix/Linux 下用于列出进程打开文件的工具。
注意关键词:
不是“普通文件”
而是“所有文件描述符”
在 Linux 中,以下对象全部通过 file descriptor (FD) 表示:
| 对象 | 是否文件 |
|---|---|
| 普通文件 | ✅ |
| 目录 | ✅ |
| TCP 连接 | ✅ |
| UDP 连接 | ✅ |
| Unix Socket | ✅ |
| 管道 pipe | ✅ |
| 匿名内存映射 | ✅ |
| 设备文件 /dev/null | ✅ |
| 磁盘块设备 | ✅ |
这就是 Linux 内核的统一抽象。
二、lsof 的底层原理
lsof 本质做了三件事:
- 遍历
/proc - 读取
/proc/<pid>/fd/ - 解析符号链接指向
例如:
1 | ls -l /proc/1234/fd |
输出类似:
1 | 3 -> socket:[402653]4 -> /var/log/app.log5 -> anon_inode:[eventpoll] |
这说明:
- FD=3 是 socket
- FD=4 是日志文件
- FD=5 是 epoll
而 lsof 做的事情,就是帮你把这些结构:
结构化 + 关联进程 + 解析网络信息
三、最基础的使用
1️⃣ 查看所有打开文件
1 | lsof |
⚠️ 非常重,生产环境慎用。
2️⃣ 查看某个进程
1 | lsof -p 1234 |
输出包含:
- cwd(当前目录)
- txt(执行文件)
- mem(内存映射)
- IPv4/IPv6
- REG(普通文件)
你会发现:
一个 Java 进程,能打开几百甚至几千个文件。
这就是“一切皆文件”的具象体现。
四、最重要的生产级场景
场景 1:排查端口占用
1 | lsof -iTCP:6443 -sTCP:LISTEN |
输出:
1 | java 1234 TCP *:8080 (LISTEN) |
比 netstat 更精准,因为:
- 可以直接看到 PID
- 可以看到进程名
- 可以过滤具体端口
场景 2:查找谁在监听端口
1 | lsof -i -P -n | grep LISTEN |
-P不解析端口名-n不解析 DNS(避免卡住)
场景 3:查看进程打开文件数量(FD 泄漏)
1 | lsof -p 1234 | wc -l |
如果数字持续增长:
说明存在 FD 泄漏
常见原因:
- 忘记关闭文件流
- socket 未关闭
- epoll FD 未释放
场景 4:排查 Too many open files
错误:
1 | EMFILEToo many open files |
排查步骤:
- 查看进程 FD 数量
1 | ls /proc/1234/fd | wc -l |
- 用 lsof 找出谁在吃FD
1 | lsof -p 1234 |
- 查 ulimit
1 | ulimit -n |
场景 5:查看 TCP 连接
1 | lsof -i tcp |
指定:
1 | lsof -i tcp:3306 |
你会看到:
1 | java -> mysql |
这直接揭示:
网络连接本质也是文件
场景 6:查看谁连接了某台远程机器
1 | lsof -i @10.0.0.5 |
场景 7:查看 Unix Domain Socket
1 | lsof -U |
你会看到:
1 | /var/run/docker.sock |
这说明:
Docker API 其实是 Unix 文件。
场景 8:查看某个文件被谁使用
1 | lsof /var/log/app.log |
场景 9:查看内存映射文件
1 | lsof | grep mem |
Java 的 jar、so 库全部会显示。
场景 10:容器排查
1 | nsenter -t <pid> -m -u -i -n -p lsof |
你会发现:
- 容器网络
- 挂载文件
- 共享 FD
都能观测到。
场景 11:排查 NFS 锁
1 | lsof | grep nfs |
场景 12:查看进程当前目录
1 | lsof -p 1234 | grep cwd |
场景 13:查看管道
1 | lsof | grep pipe |
Shell 管道本质:
1 | 匿名文件 |
五、lsof 如何证明“一切皆文件”
我们做个简单实验:
启动一个简单服务:
1 | python3 -m http.server 8000 |
然后:
1 | lsof -p <pid> |
你会看到:
| 类型 | 说明 |
|---|---|
| cwd | 当前目录 |
| txt | Python 可执行 |
| mem | libc |
| IPv4 | 监听端口 |
| pipe | stdout |
| anon_inode | epoll |
这说明:
- 网络是文件
- 终端是文件
- 内存映射是文件
- 管道是文件
Linux 用 file abstraction 统一了:
存储 + 通信 + 设备 + 进程交互
这是一种极其优雅的内核设计。
六、lsof vs 其他工具
| 工具 | 能力 |
|---|---|
| ps | 进程信息 |
| netstat | 网络连接 |
| ss | socket 状态 |
| lsof | 文件 + 网络 + FD 全部 |
lsof 是统一视角。
七、架构师视角:为什么这很重要?
理解 lsof,你会获得三种能力:
1️⃣ 抽象能力
Linux 通过 file descriptor 统一所有资源。
这类似于:
- JVM 一切皆对象
- Kubernetes 一切皆 API
- Unix 一切皆流
2️⃣ 故障排查模型
当线上出问题:
- 端口占用
- 磁盘满
- FD 泄漏
- 连接异常
你可以问自己:
是哪个文件没释放?
3️⃣ 性能优化视角
高并发服务器核心是:
- socket 数量
- epoll FD 数量
- 文件句柄上限
这些都能用 lsof 观测。
八、终极理解
Linux 内核本质上维护:
1 | task_struct |
所有资源都通过:
1 | int fd |
访问。
而 lsof:
就是 file descriptor table 的“可视化仪表盘”。
九、一个思维升级
当你下次看到:
1 | Too many open files |
不要只想到 ulimit。
而是要想到:
系统资源抽象失控了。
这才是真正的架构视角。
参考文档:https://man7.org/linux/man-pages/man8/lsof.8.html
十、总结
lsof 不只是一个命令。
它揭示的是 Linux 的核心哲学:
抽象统一,接口统一,资源统一。
当你真正掌握它:
- 你会更快排查问题
- 你会理解内核设计
- 你会对系统资源有“可观测感”



