/proc/[pid]/fd/ 是最准确的进程句柄详情来源,因其为内核实时维护、无权限过滤且包含所有 fd;lsof -p 则提供语义化解读,二者配合使用才能全面分析。

查某个进程的句柄详情,直接看 /proc/[pid]/fd/ 目录最准
/proc/[pid]/fd/ 是内核为每个进程维护的实时句柄映射目录,里面每个符号链接对应一个打开的文件描述符(fd)。它不经过用户态工具解析,没有权限过滤、不跳过内核内部 fd(如 eventfd、timerfd),比 lsof -p 更底层、更完整。
-
ls -l /proc/1234/fd/显示所有 fd 及其指向的目标(如socket:[1234567]、/var/log/app.log、pipe:[89012]) -
ls -1 /proc/1234/fd/ 2>/dev/null | wc -l统计数量(2>/dev/null忽略权限拒绝错误) - 普通用户只能读自己进程的
/proc/[pid]/fd/;查别人进程需sudo权限
lsof -p [pid] 适合带语义的排查,但要注意输出干扰
lsof -p 1234 输出含字段:COMMAND、PID、USER、FD、TYPE、DEVICE、SIZE/OFF、NODE、NAME,对定位“为什么占这么多”很有用。
- FD 列出现大量数字(如
15u、1024r)且 NAME 指向同一日志或 socket → 很可能没 close - NAME 显示
(deleted)→ 文件已 unlink,但进程仍持有句柄,磁盘空间不释放 - TYPE 是
sock且 STATE 为CLOSE_WAIT→ TCP 连接未正确 shutdown,积压在本地 - 注意:
lsof -p默认包含表头行,统计时要lsof -p 1234 | tail -n +2 | wc -l才准确
别用 lsof | wc -l 代替单进程统计
lsof | wc -l 看起来省事,但问题很多:
- 普通用户执行会因权限不足中断(遇到其他用户进程报
permission denied),导致漏数 - 输出含空行、警告、表头,
wc -l计数不可靠 -
lsof本身有开销,在高并发场景下可能超时或返回不全 - 容器内执行时,
lsof默认看到的是宿主机视角,而/proc/[pid]/fd/在容器里是隔离后的路径,结果更真实
快速定位异常 fd 类型,用 lsof -p 加过滤
光看总数不够,得知道“都是什么”。
- 查所有网络 socket:
lsof -p 1234 -a -i - 查所有普通文件:
lsof -p 1234 -a -d ^cwd,^mem,^DEL(排除工作目录、内存映射、已删文件) - 查重复打开的某路径:
lsof -p 1234 | grep '/tmp/cache' - 查 fd 数 > 100 的进程并排序:
lsof -n | awk '{print $2}' | sort | uniq -c | awk '$1 > 100 {print $0}' | sort -nr
真正要确认一个进程到底打开了什么,/proc/[pid]/fd/ 是唯一不撒谎的来源;lsof -p 是帮你读懂那些数字链接背后含义的翻译器。两者配合用,才不会把 socket:[12345] 当成无关紧要的噪音忽略掉。


















