lsof /path/to/file 可查占用指定文件的进程,需注意权限、路径完整性及软链接处理;输出中PID为进程ID,FD含txt/cwd/DEL等标识;查不到时可加-u或-p参数,或直接检查/proc/PID/fd/。

lsof 查看文件被哪个进程占用
直接用 lsof 命令就能查出谁在用某个文件,前提是当前用户有权限读取对应进程的文件描述符信息(比如非 root 用户查系统进程可能看不到部分结果)。
最常用写法是:lsof /path/to/file。如果文件正被写入、打开、映射或甚至只是被 cwd(当前工作目录)指向,它都会列出来。
- 输出字段中
PID是进程 ID,COMMAND是进程名,TID(如有)是线程 ID,FD表示文件描述符类型(如txt表示可执行文件,cwd是当前目录,DEL表示已删除但仍被占用的文件) - 若提示
command not found,说明没装lsof:Ubuntu/Debian 用sudo apt install lsof,CentOS/RHEL 用sudo yum install lsof或sudo dnf install lsof - 路径必须写全——
lsof foo.log不会自动匹配当前目录下的foo.log,得写成lsof ./foo.log或lsof /home/user/foo.log
lsof 查不到进程?可能是权限或路径问题
普通用户运行 lsof 默认只能看到自己启动的进程;root 才能看全部。如果你查一个明显被占用的日志文件却没结果,先确认是否是其他用户(如 www-data、nginx)在用。
- 加
-u username指定用户,例如lsof -u www-data /var/log/nginx/access.log - 加
-p PID可反向查某个进程打开了哪些文件,适合定位异常句柄泄漏 - 注意软链接:如果路径是软链接,
lsof默认显示的是链接本身;加-L参数可跟随链接解析真实路径 - 已删除但仍被占用的文件会显示为
(deleted),FD 列可能是REG或mem,这种状态常见于未重启的服务仍在写旧文件描述符
强制释放文件占用前务必确认进程用途
lsof 只负责“看”,不负责“杀”。查到 PID 后别急着 kill,尤其要避开以下几类:
- 系统关键进程(如
systemd、dbus、rsyslog)——误杀可能导致服务中断 - 数据库进程(如
mysqld、postgres)——直接 kill 可能引发数据不一致 - Web 服务器主进程(如
nginx: master process)——应发reload或reopen信号而非 kill - 真正安全的操作是:对日志类文件,优先用服务自带 reload 机制(如
sudo nginx -s reopen);对临时调试场景,可用kill -HUP PID触发重载(前提是程序支持)
替代方案:/proc/PID/fd 下手动验证
当 lsof 不可用或你想绕过它直接观察,Linux 内核提供了原始接口:/proc/PID/fd/ 是每个进程打开的文件描述符符号链接目录。
- 例如查 PID 1234 占用了什么文件:
ls -l /proc/1234/fd/ | grep "your_filename" - 注意:该目录只对进程所有者和 root 可读;且某些 FD(如 socket、eventfd)不会显示具体路径,只显示类型
- 比
lsof更底层,但无法跨进程聚合搜索——你得先知道 PID,不能像lsof /path那样反向查找
lsof 够用,但容易忽略两点:一是没切到 root 就查不到系统级进程,二是看到 (deleted) 状态时误以为文件已释放,其实句柄还活着。










