fuser不适合查单个文件,因其按inode或挂载点聚合扫描,对普通文件识别率低;它真正擅长的是目录、挂载点和端口排查,查文件应优先用lsof。

fuser 不能直接查“某个文件”被谁占用——它查的是路径,且对普通文件支持弱;真要查单个文件,优先用 lsof -t 或 lsof -p 配合 grep,fuser 更适合目录、挂载点、端口。
为什么 fuser 查单个文件经常没输出或报错
fuser 的设计目标是快速定位“活跃资源占用”,它默认按 inode 或挂载点聚合扫描,对普通文件(尤其是未被 mmap、未打开、未作为 cwd 的)识别率低。常见现象包括:
- 运行
fuser /tmp/test.log返回空,但lsof /tmp/test.log明明显示vim正在编辑它 - 报
No such file or directory,其实文件存在——本质是权限不足,fuser无法读取/proc/PID/fd/下的符号链接 - 即使查到了,ACCESS 列只显示
f(file),不告诉你 fd 号、打开模式(O_RDONLY/O_RDWR)、是否被截断重写
fuser 查目录或挂载点才真正靠谱
这是 fuser 最稳定、最常用的场景,比如卸载 U 盘前确认是否被占用:
-
fuser -v /mnt/usb:列出所有访问该挂载点的进程,重点关注cwd(当前工作目录)、mem(共享库映射)、txt(执行文件)类型 -
fuser -m -v /dev/sdb1:显式指定块设备,避免因挂载点路径变化导致漏查 -
fuser -s /mnt/usb:静默模式,仅返回退出码(0=有占用,1=无占用),适合写进 shell 脚本做判断 - 路径末尾不要加
/:fuser /var/log✅,fuser /var/log/❌(某些版本会匹配失败)
查端口比查文件更顺手
fuser 对网络端口的支持很成熟,语法简洁、响应快:
-
fuser 80/tcp:查 TCP 80 端口,输出就是一串 PID,干净利落 -
fuser -v 22/tcp:加-v显示用户、命令、端口状态(listen或connect) -
fuser -k 3000/tcp:直接杀掉监听 3000 端口的进程(注意:只杀主进程,子进程可能残留) - 信号要显式指定:
fuser -k -TERM 8080/tcp比默认SIGHUP更可控,避免 nginx 重载后继续占端口
真正想查“某个文件”被谁打开?换 lsof
当明确目标是单个文件(如日志、配置、socket 文件),lsof 是更可靠的选择:
-
lsof +D /var/log:递归查整个目录下所有被打开的文件(比fuser -v /var/log更细,但慢) -
lsof /etc/hosts:直接查该文件,输出含 PID、USER、FD(如4r表示 fd=4,只读)、TYPE、NODE -
lsof -t /tmp/my.sock:只输出 PID,方便管道给kill,例如kill $(lsof -t /tmp/my.sock) - 注意权限:
lsof同样需要sudo才能看到其他用户的打开文件
别指望 fuser 把所有资源类型一网打尽。它快、轻、适合脚本判断和批量操作,但细节深度远不如 lsof。查文件就老实用 lsof,查挂载点或端口再亮出 fuser——这个分工边界,比任何参数技巧都重要。











