lsof 能看到已删除但未释放的文件,因为文件被 unlink 后只要进程仍持有 fd,inode 就不会被释放,lsof +l1 可精准列出 link count 为 0 的打开文件。

为什么 lsof 能看到已删除但未释放的文件?
Linux 中,当一个进程打开文件后,即使该文件被 rm 删除,只要进程仍持有该文件的文件描述符(fd),内核就不会真正回收磁盘空间——因为文件的 inode 仍被引用。这种“已删除但未关闭”的文件在 lsof 输出中会标记为 (deleted),是排查磁盘空间不释放问题的关键线索。
常见场景包括:日志轮转后旧进程仍在写入、Web 服务器未重启导致访问已删日志、后台任务持续写入被误删的临时文件。
用 lsof +L1 快速定位已删文件句柄
+L1 是 lsof 的专用选项,专门列出所有链接计数(link count)为 0 的打开文件,即已被 unlink() 但未关闭的文件。它比手动 grep (deleted) 更可靠,因为后者可能匹配到路径含 deleted 字样的正常文件。
- 运行
lsof +L1查看全局情况;权限不足时加sudo - 若只关心某用户,用
lsof -u username +L1 - 若怀疑某目录下有残留(如
/var/log),可结合lsof +D /var/log +L1(注意:+D 递归扫描开销大,慎用于大目录) - 输出中
SIZE/OFF列显示当前已写入大小,直接反映占用的空间量
lsof 输出里哪些字段最关键?
典型行:nginx 1234 www-data 5w REG 253,1 1073741824 123456 /var/log/nginx/access.log (deleted)
重点关注:
-
PID:进程 ID,用于后续 kill 或调试 -
TID(如有):线程 ID,某些多线程服务需细粒度定位 -
FD列的数字(如5w):5是 fd 编号,w表示写入模式,u表示读写,确认是否还在活跃写入 -
SIZE/OFF:实际占用空间大小,单位字节;若值极大(如超 GB),说明该句柄正在持续膨胀 -
(deleted):必须存在,否则不是目标对象
释放空间前务必确认进程状态
直接 kill 进程能立即释放空间,但可能引发服务中断或数据丢失。操作前先判断:
- 用
ps -p PID -o pid,ppid,comm,args确认进程用途和启动方式 - 检查是否为 systemd 服务:
systemctl status PID或systemctl --all --state=running | grep PID - 若属日志类进程(如
rsyslogd,journalctl),优先尝试kill -USR1 PID触发日志 reopen(需服务支持) - 若确定可重启,用
systemctl restart servicename比kill -9更安全
注意:lsof +L1 不会显示已退出但子进程继承了 fd 的情况(极少见),也不捕获内核线程持有的句柄;若空间仍不释放,需检查是否有容器或 chroot 环境隔离导致 lsof 视角受限。











