在Linux系统中,lsof命令是排查进程文件占用的利器,掌握基础参数组合就能应对大多数场景。本文详解四种典型应用场景,助你精准定位文件占用问题。
直接用 lsof 查进程打开的文件,绝大多数情况不需要"高级用法"——基础选项组合就能解决 95% 的问题。所谓"高级",其实是把几个常用参数串起来应对具体场景,而不是堆砌冷门开关。
最常见需求:知道一个进程卡住了、占着磁盘或端口,想看它到底在读写什么。
lsof -p 1234 是起点,但默认输出太长,建议加 -n(不解析主机名/端口名)和 -P(不查服务名),避免卡顿或 DNS 查询延迟lsof -p 1234 -a -d ^cwd,^txt,^mem -a -t 中的 -d ^cwd,^txt,^mem 排除当前目录、代码段、内存映射,剩下多为实际读写的文件-p 必须用 root 权限才能看到其他用户的进程;普通用户执行时,lsof -p $PID 只能查自己启动的进程端口被占用、服务起不来、连接连不上?lsof -i 是第一响应工具,但写法有坑。
lsof -i :8080 能查到或连接 8080 的所有进程,但默认会解析域名和端口名(比如把 80 显示成 http),加 -n -P 更快更准lsof -i tcp:3306 或 lsof -i udp:53,不要写成 lsof -i tcp -i :3306 —— 这样是 AND 逻辑,但 -i tcp 本身不含端口条件,结果可能为空lsof -i4 :22 比 lsof -i :22 更明确,避免因双栈配置导致漏掉在 :::22 的 sshd卸载失败报 device is busy,本质是进程 cwd、root、或打开了该目录下的文件。不能只靠 lsof /path。
lsof +D /var/log 递归扫描整个目录树,速度慢、权限要求高(需能遍历子目录),且容易因权限不足中断lsof +d /var/log(非递归),只扫一级目录下的打开文件,配合 grep 快速定位:lsof +d /var/log | grep REG
cwd 和 rtd 类型:进程当前工作目录是 /var/log,哪怕没打开任何文件,也会阻止 umount —— 这类条目在 lsof +d /var/log 输出里 FD 列显示为 cwd,不是 REG
日志轮转后 df 显示磁盘满,但 du -sh /var/log 却不大?大概率是文件被删了,但进程还拿着 fd。
lsof | grep deleted 是标准做法,但输出中 NAME 列会显示类似 /var/log/nginx/access.log (deleted)
systemctl restart nginx),而非直接 kill —— 强杀可能引发服务异常;若无法重启,lsof -p PID 再确认是否只有这一个 deleted 文件在占空间通过以上四个典型场景的分析可见,lsof命令的关键在于参数组合与权限控制。合理运用基础参数组合,配合root权限使用,能有效解决绝大多数文件占用问题,无需过度依赖复杂参数。