最常用且最可靠的方案是sudo lsof /path/to/file,需用绝对路径并加sudo获取权限;若为空,常见原因包括权限不足、路径错误或文件未被打开;name列含(deleted)表明文件已删但句柄仍占磁盘空间。

lsof /path/to/file 直接查占用进程
这是最常用也最可靠的方案。lsof 会扫描所有进程的文件描述符,精准匹配路径(注意:需完整路径,软链接目标不自动展开)。如果返回空,常见原因有三个:没权限、路径写错、或该文件根本没被任何进程打开。
使用时必须加 sudo,否则普通用户看不到其他用户的进程和系统级文件句柄。例如:
sudo lsof /var/log/nginx/access.log
输出中重点关注 PID、USER、FD(如 12w 表示写入模式的第12号描述符)、NAME 列。若 NAME 显示 /path/to/file (deleted),说明文件已被 rm 删除,但进程仍持有句柄——磁盘空间不会释放,得 kill 进程或重启服务。
fuser 命令快速定位并可选终止
fuser 更轻量,适合快速判断“谁在用”,不关心细节。它默认只输出 PID,不显示用户或打开模式,但支持直接发信号终止进程。
常见组合:
-
fuser /path/to/file—— 只打印 PID 列表 -
fuser -v /path/to/file—— 加-v输出类似lsof的详细信息(含用户、访问类型) -
fuser -k /path/to/file—— 强制 kill 所有占用进程(慎用!) -
fuser -k -TERM /path/to/file—— 发送SIGTERM而非默认的SIGKILL,给进程优雅退出机会
注意:fuser 对符号链接路径可能不敏感,建议用真实路径;且它不报告已删除但仍被占用的文件((deleted) 状态),这点不如 lsof 全面。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
用 /proc/PID/fd 手动验证,绕过工具依赖
当 lsof 或 fuser 不可用(比如最小化系统、容器内无包管理),或者你想确认某个特定 PID 是否真打开了该文件,就直接翻 /proc。
步骤很直白:
- 先用
ps aux | grep 关键词或pgrep -f 关键词锁定可疑 PID - 执行
ls -l /proc/<code>PID/fd/ | grep "filename" - 结果里如果看到类似
lr-x------ 1 root root 64 Sep 29 10:00 12 -> /var/log/app.log,就坐实了
这个方法完全依赖内核接口,零外部依赖,但无法反向查询(即不能从文件找 PID,只能从 PID 查文件)。
为什么有时查不到?几个关键盲区
不是命令失效,而是你查的位置不对:
- 路径大小写或符号链接未展开:
/opt/app/logs和/opt/app/logs/(末尾斜杠)在某些场景下被视为不同路径 - 进程以相对路径打开文件,而你查的是绝对路径——
lsof只匹配当前打开时使用的路径字符串 - 文件系统挂载点变更后未重载服务:旧进程仍持老路径句柄,新进程用新路径,容易漏掉前者
-
lsof默认不扫描 NFS 或某些 FUSE 文件系统,需加-n参数强制识别
真正难排查的,往往是多个服务共用一个日志目录、或 systemd 服务用 StandardOutput=journal 重定向后绕过了文件句柄——这时候得结合 journalctl -u service-name 看实际输出去向。










