lsof +L1是识别已被删除但进程仍占用文件的最直接方法,它筛选链接计数为0的文件;配合grep 'deleted'可兼容旧版本,-n避免DNS延迟,-p聚焦特定进程;空间释放需通过优雅重启、SIGHUP重载或谨慎清空/proc/pid/fd/文件实现。

lsof -P 本身不能直接查看“已被删除但被进程占用的文件”,真正起作用的是 lsof +L1(或配合 -n、-p 等选项)。-P 只是禁用端口号转服务名,和“已删文件”无关。要释放被占用的隐性磁盘空间,关键在于识别并处理处于 deleted 状态的打开文件。
识别被删除但仍被占用的文件
运行以下命令可列出所有标记为 (deleted) 的打开文件:
- lsof +L1 —— 最直接有效的方式,只显示链接计数为 0(即文件已被 unlink,但仍有进程持有 fd)的条目
- lsof | grep 'deleted' —— 兼容性更强,适用于老版本 lsof(+L1 在某些旧系统中不可用)
- 加 -n 避免 DNS 解析延迟:lsof +L1 -n
- 加 -p PID 可聚焦特定进程:lsof +L1 -n -p 1234
理解输出含义与空间释放逻辑
典型输出类似:
java 1234 user 100w REG 253,0 2147483648 123456 /var/log/app.log (deleted)
-
最后一列 显示
(deleted),说明该文件路径已被unlink()或rm删除,但进程仍通过文件描述符(如 fd 100)读写它 - 磁盘空间未释放 是因为内核仅在所有对该 inode 的引用(包括打开的 fd)全部关闭后,才真正回收数据块
- 只要进程不关闭 fd、也不退出,空间就持续被“隐性占用”
安全释放空间的常用方法
-
重启对应进程:最稳妥。例如
systemctl restart myapp或kill -15 1234(先尝试优雅终止) -
向进程发送日志重载信号(如 logrotate 后):很多服务支持
SIGHUP关闭旧日志 fd 并打开新文件,例如kill -HUP 1234 -
手动清空文件内容(慎用):若进程以追加模式(
O_APPEND)写入且支持截断,可执行echo > /proc/1234/fd/100—— 这会清空该 fd 对应的文件内容,立即释放空间,但可能影响程序行为,仅建议在明确理解其 I/O 模式时使用 - 避免 kill -9:强制终止虽能释放空间,但可能导致数据丢失或状态不一致,优先选 graceful shutdown
预防隐性空间占用的建议
- 配置 logrotate 时启用
copytruncate(对无法重载日志的服务),或确保应用支持SIGHUP重开日志 - 监控
/proc/*/fd/下的(deleted)文件数量,例如:lsof +L1 2>/dev/null | wc -l - 定期检查大尺寸 deleted 文件:
lsof +L1 -s | sort -k 7 -hr | head -10(需 lsof 支持 -s 显示文件大小) - 开发阶段避免长期持有已删除大文件的 fd,尤其注意临时文件清理逻辑


















