lsof /path/to/file 返回空结果主因是权限不足或路径错误:未加sudo导致无法查看root等进程的fd,或未用绝对路径、未处理软链接;文件被删后句柄仍存时需用sudo lsof +l1 | grep。

直接用 lsof /path/to/file,但 90% 的“查不到”问题都出在权限或路径写法上,不是命令本身失效。
为什么 lsof /path/to/file 经常返回空?
常见错误现象是:文件明明在被 tail -f 或 nginx 写入,lsof /var/log/app.log 却没输出。
- 没加
sudo:普通用户无法读取 root 或 www-data 进程的/proc/PID/fd/,必须sudo lsof /path/to/file - 路径不完整:不能写
lsof app.log或lsof ./app.log,必须是绝对路径,比如/home/user/app/app.log - 软链接未解析:如果
/var/log/current.log是指向真实日志的符号链接,默认查的是链接路径本身;要查目标文件,加-L参数:sudo lsof -L /var/log/current.log - 文件已被
rm但句柄未关:此时lsof /path/to/file查不到,得用sudo lsof +L1 | grep 'app.log'
如何确认某个进程是否真在读写该文件?
lsof 输出里的 FD 列才是关键判断依据,不是只要有匹配行就等于“正在占用”。
-
REG+w或u(read-write / read-write with lock):说明进程正以可写方式打开该文件,大概率在写入 -
txt:进程正在执行这个文件(如二进制),不是读写数据文件 -
cwd:只是当前工作目录设为此路径,不代表在操作该文件 -
DEL或 NAME 列末尾带(deleted):文件已删,但 fd 仍被持有,磁盘空间不会释放
如果只看到 cwd,别急着 kill——它可能只是个 shell 工作目录,和文件内容无关。
查不到时,绕过 lsof 直接翻 /proc
某些容器或最小化系统没装 lsof,或者你想验证 lsof 是否漏报,可以手动检查内核接口:
- 先用
ps aux | grep keyword或pgrep -f nginx找疑似 PID - 再执行
ls -l /proc/<pid>/fd/ 2>/dev/null | grep 'app\.log'</pid>—— 注意这里用grep做模糊匹配,因为 fd 链接名是数字,目标路径藏在箭头后 - 确认是否有效占用:
readlink /proc/<pid>/fd/7</pid>看是否指向目标文件,且lsof -d 7 -p <pid></pid>显示状态为REG
注意:/proc/<pid>/fd/</pid> 下出现匹配,不等于当前正在读写——它可能是历史打开后未 close 的 fd,真正活跃状态得靠 lsof -p <pid></pid> 或观察 lsof -t 输出是否持续变化。
别用 fuser 查单个文件
fuser /path/to/file 在多数场景下不可靠,尤其对普通日志、配置文件。
- 它按 inode 或挂载点聚合扫描,对未 mmap、未 open、仅通过重定向访问的文件识别率低
- 常出现
fuser /tmp/test.log返回空,但lsof /tmp/test.log明确显示 vim 正在编辑 -
fuser不显示 fd 号、打开模式(O_RDWR还是O_RDONLY)、是否被截断,信息粒度太粗 - 真正适合它的场景是:查目录占用(
sudo fuser -v /mnt/data)、查端口(fuser 80/tcp)、脚本里做布尔判断(fuser -s /path && echo busy)
查“具体哪个外部程序在读写某个文件”,lsof 是唯一靠谱的选择;fuser 只能当辅助交叉验证,不能替代。











