直接用 lsof -p PID 查进程打开的文件需加 -n -P 避免解析卡顿,普通用户仅能查自身进程,加 sudo 才可见全部;-d ^cwd,^txt,^mem 可过滤非实际读写文件,/proc/PID/fd 提供内核级验证。

直接用 lsof -p PID 就能看到进程打开的所有文件,但默认输出杂乱、慢、权限受限——关键不是“能不能查”,而是“查得准不准、快不快、有没有漏”。
查指定 PID 打开的文件:加 -n -P 避免卡顿和误判
不加参数的 lsof -p 1234 可能卡几秒,甚至返回空(尤其在 DNS 不通或端口服务名解析失败时)。这是因为默认会尝试反向解析 IP 和端口名。
- 必须加上
-n(跳过主机名解析)和-P(跳过端口名解析),例如:sudo lsof -n -P -p 1234 - 普通用户执行时,
lsof -p $PID只能看到自己启动的进程;查别人(比如 nginx、mysql)必须加sudo -
FD列里的cwd(当前工作目录)、txt(可执行文件)、mem(内存映射)不算“正在读写”的文件,如需聚焦实际 I/O,可用-a -d ^cwd,^txt,^mem过滤
不知道 PID?用 lsof -c 进程名 反向定位
-c 匹配的是 ps 输出中的 COMMAND 字段,即二进制 basename,不是脚本名或完整路径。
-
sudo lsof -c python3会匹配/usr/bin/python3 /opt/app/main.py,但不会匹配main.py本身 - 多个进程名用多个
-c:例如sudo lsof -c nginx -c php-fpm是 OR 关系,不是 AND - 注意大小写敏感,
nginx≠Nginx;如果进程名含空格(如 Java 应用),-c失效,得先用pgrep -f或ps aux | grep拿 PID
查目录被谁占用(比如 umount 报 device busy)
卸载失败时,问题往往不在“某个文件”,而在进程把该目录设为 cwd 或 rtd(root directory),哪怕没打开任何子文件也会阻塞。
- 别用
lsof +D /path(递归扫描)——太慢,还容易因权限中断;改用lsof +d /path(仅一级目录) - 重点看
FD列是cwd或rtd的行,这类条目不显示具体文件名,但正是它们让umount失败 - 配合
grep REG能快速筛出真正打开的普通文件:lsof +d /var/log | grep REG
绕过 lsof:用 /proc/PID/fd/ 直接验证
当系统没装 lsof,或你想确认符号链接是否被正确解析、或怀疑权限绕过时,/proc 是唯一可信来源。
-
ls -l /proc/1234/fd/列出所有 fd 符号链接,目标含(deleted)表示文件已被删但句柄未关 -
readlink /proc/1234/fd/7查看 fd 7 指向的真实路径(支持解析软链) - 注意:
/proc/PID/fd/只能查已知 PID;而lsof /path/to/file是反向查——给路径就能找 PID,这才是它不可替代的核心能力
最常被忽略的一点:lsof 输出里 NAME 列显示的路径可能是相对路径、软链目标、甚至已删文件的原始 inode 路径,不能直接当成“当前磁盘上存在的文件”来操作。真要恢复或清理,得结合 /proc/PID/fd/ 下的实际链接状态判断。


















