Linux lsof 命令深度解析:从文件描述符到进程追踪

摘要lsof(List Open Files)是 Linux 系统排查问题的利器。本文从核心原理(/proc 文件系统)出发,系统讲解端口占用排查、已删除文件空间找回、进程文件查看等高频场景,并涵盖组合查询、输出格式化等高级技巧与实战案例,帮你快速定位线上故障。

线上服务器突然报磁盘空间不足,df 一看还有 30%,但 du 统计出来却只有 10%。这种情况你遇到过吗?大概率是某个进程打开了已删除的文件,文件句柄没释放。

这时候 lsof 就派上用场了。

lsof 是什么

lsof 全称 List Open Files ,用于列出当前系统所有打开的文件。在 Linux 里,一切皆文件------普通文件、目录、网络套接字、管道、设备......这些都是文件。所以 lsof 能看到的不只是文件,还有网络连接、进程通信等。

核心原理:从 /proc 文件系统读取

lsof 的数据来源是 /proc 文件系统。每个进程在 /proc/<pid>/fd/ 目录下都有文件描述符的符号链接:

bash 复制代码
# 查看进程 1234 打开的文件描述符
ls -la /proc/1234/fd/

lrwx------ 1 root root 64 May 19 10:00 0 -> /dev/null
lrwx------ 1 root root 64 May 19 10:00 1 -> /dev/pts/0
lrwx------ 1 root root 64 May 19 10:00 2 -> /dev/pts/0
lrwx------ 1 root root 64 May 19 10:00 3 -> /var/log/app.log
lrwx------ 1 root root 64 May 19 10:00 4 -> socket:[12345]

lsof 本质上是遍历这些信息并格式化输出。理解这一点,遇到权限问题或特殊情况时就知道该怎么排查了。

常用场景与命令

1. 查看端口占用

bash 复制代码
# 查看谁在监听 8080 端口
lsof -i :8080

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx    1234 root   6u  IPv4  12345      0t0  TCP *:8080 (LISTEN)

# 只显示 TCP 连接
lsof -i TCP:8080

# 查看所有网络连接
lsof -i

输出字段解释:

  • FD : 文件描述符,u 表示读写模式
  • TYPE: 文件类型,IPv4/IPv6 表示网络套接字
  • NODE: 内核中的 inode 编号
  • NAME: 文件名或连接信息

2. 查看进程打开的文件

bash 复制代码
# 查看指定进程打开的所有文件
lsof -p 1234

# 查看多个进程
lsof -p 1234,5678,9012

# 只看普通文件(排除套接字、管道等)
lsof -p 1234 | grep REG

3. 找回已删除但仍占空间的文件

这是 lsof 最经典的用法。文件被删除后,如果有进程仍持有其句柄,磁盘空间不会释放:

bash 复制代码
# 找出已删除但仍被打开的文件
lsof | grep deleted

java      1234 root  1w  REG  8,1  1073741824  12345 /var/log/app.log (deleted)

# 恢复文件内容(通过 /proc)
cp /proc/1234/fd/1 /tmp/recovered.log

# 彻底释放空间:杀死进程或重启服务
kill -HUP 1234

4. 查看用户打开的文件

bash 复制代码
# 查看指定用户打开的文件
lsof -u nginx

# 排除某个用户
lsof -u ^root

# 查看多个用户
lsof -u nginx,mysql

5. 查看目录被谁占用

bash 复制代码
# 查看谁在使用 /var/log 目录
lsof +D /var/log

# 递归查看(+D 会递归,+d 不会)
lsof +d /var/log

6. 查看文件被谁打开

bash 复制代码
# 查看指定文件被哪个进程打开
lsof /var/log/app.log

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
tail     5678 root   3r   REG  8,1     1024  12345 /var/log/app.log

高级技巧

组合条件查询

bash 复制代码
# 查看 nginx 进程的网络连接
lsof -c nginx -i

# 查看指定用户的 TCP 连接
lsof -u nginx -i TCP

# 查看指定进程的网络连接
lsof -p 1234 -i

# 使用 AND 逻辑(同时满足)
lsof -a -c nginx -i TCP

# 使用 OR 逻辑(默认)
lsof -c nginx -c mysql

输出格式化

bash 复制代码
# 只输出 PID
lsof -t -i :8080

# 配合 kill 使用
kill -9 $(lsof -t -i :8080)

# 输出为 CSV 格式(便于脚本处理)
lsof -F pcn | awk '/^p/{pid=substr($0,2)} /^c/{cmd=substr($0,2)} /^n/{print pid","cmd","substr($0,2)}'

查看块设备

bash 复制代码
# 查看谁在使用 /dev/sda1
lsof /dev/sda1

# 查看所有块设备
lsof +c 0 | grep -E "^COMMAND|/dev/sd"

性能考量

lsof 需要遍历所有进程的 /proc/<pid>/fd/ 目录,在进程数很多的系统上会比较慢。几个优化建议:

  1. 缩小查询范围:指定进程、用户或端口,避免全量扫描
  2. 使用 -n 参数:不解析主机名,加快输出速度
  3. 使用 -P 参数:不解析端口名,直接显示数字
bash 复制代码
# 快速查询,不解析名称
lsof -n -P -i :8080

与其他工具对比

工具 主要用途 优势
lsof 列出打开的文件 全面,支持网络、文件、设备
fuser 查看谁在使用文件/套接字 轻量,适合脚本
ss 查看套接字统计 快速,取代 netstat
netstat 查看网络连接 传统工具,逐渐被 ss 取代
bash 复制代码
# fuser 查看 8080 端口占用
fuser 8080/tcp

# ss 查看 8080 端口
ss -tlnp | grep 8080

实战案例

案例 1:排查 "Too many open files"

bash 复制代码
# 查看系统打开文件限制
ulimit -n

# 查看指定进程打开的文件数量
lsof -p 1234 | wc -l

# 查看所有进程打开文件数排序
lsof | awk '{print $1}' | sort | uniq -c | sort -nr | head

案例 2:排查磁盘空间消失

bash 复制代码
# 现象:df 显示空间不足,但 du 统计正常
df -h
du -sh /*

# 用 lsof 找出罪魁祸首
lsof | grep deleted | sort -k7 -nr | head

# 解决:重启对应服务或杀死进程

案例 3:排查服务启动失败(端口被占用)

bash 复制代码
# 启动服务报 "Address already in use"
lsof -i :8080

# 强制杀掉占用端口的进程
kill -9 $(lsof -t -i :8080)

总结

lsof 是排查线上问题的利器,熟练掌握能帮你快速定位:

  • 端口占用问题
  • 磁盘空间消失问题
  • 文件锁定问题
  • 网络连接追踪

记住几个核心参数:-i 查网络、-p 查进程、-u 查用户、+D 查目录。遇到问题时,先想到 /proc 文件系统,再配合 lsof 工具,基本都能找到答案。


相关工具

相关推荐
qq3621967051 小时前
facebook是什么意思?新手从零到精通完全指南
运维·服务器·facebook
勿芮介1 小时前
【研发工具】Jenkins镜像源配置问题及解决方案
运维·servlet·jenkins
qq_312920111 小时前
如何将Nginx响应时间从500ms降至50ms
运维·nginx
BingoGo2 小时前
免费可商用 PHP 管理后台 CatchAdmin V5.3.1 发布 后台打包直降 5s 内
后端·php
andlbds2 小时前
解决Ubuntu20.04进入系统卡死在厂商Logo界面问题
linux·ubuntu
MIXLLRED2 小时前
解决: Ubuntu 22.04上树莓派4B扩展板ROS2兼容性修复指南
linux·ubuntu·树莓派
zizle_lin2 小时前
CentOS配置yum源
linux·运维·centos
JaguarJack2 小时前
免费可商用 PHP 管理后台 CatchAdmin V5.3.1 发布 后台打包直降 5s 内
后端·php·laravel
志栋智能2 小时前
超自动化运维:如何降低人为错误?
大数据·运维·网络·人工智能·自动化