用 lsof 查清「谁占用了文件或端口」
服务起不来、删不掉文件、卸载报 Device busy——多数时候是某个进程还握着资源。lsof(list open files)在 Linux 上几乎是排查占用的第一选择:一切皆文件,它把进程打开的普通文件、目录、套接字都列出来,比空想「是不是缓存」靠谱得多。
查某个文件被谁打开
sudo lsof /var/log/nginx/access.log
输出里的 COMMAND、PID、USER 直接告诉你是谁。想确认某个目录下有没有进程在用:
sudo lsof +D /var/www/html
+D 会递归扫目录,文件多时较慢,适合临时排查,不适合塞进高频监控。若只关心某个挂载点,也可以先 df 定位设备,再缩小到子目录,减少无关键输出。
查端口占用(和 ss 互补)
只看谁占用了 8080:
sudo lsof -iTCP:8080 -sTCP:LISTEN
对比:ss -lntp 更适合「先扫一遍监听表」;lsof -i 在需要看到完整命令行、或确认 UDP/已建立连接时更直观。例如查看本机到某地址的出站连接:
sudo lsof -i @192.168.1.10:443
发布后旧进程没退干净时,先用上面两条确认监听者,再决定是 kill -TERM 还是查 systemd 单元有没有残留。
查已删除但仍占空间的文件
磁盘满了,但 du 对不上 df?常见原因是进程还握着已删除的文件句柄:
sudo lsof +L1
+L1 列出链接数小于 1(通常即已删)但仍打开的文件。找到 PID 后,重启对应服务或结束进程,空间才会真正释放。日志轮转后磁盘没降,多半就是这类情况:先 lsof +L1 | grep '(deleted)',再重启写日志的那个服务。
按进程看它打开了什么
sudo lsof -p 1234
排查配置是否读对、日志是否写到预期路径时很有用。加上 -a -d cwd 还可以看该进程的当前工作目录,避免「相对路径其实指到了别处」。对 Java / Node 这类常开大量文件的进程,可再加 | grep -E 'log|conf|cwd' 收窄视野。
常见组合拳
删文件报 busy:
sudo lsof +D /path/to/dir | head
sudo kill -TERM <pid>
发布后端口仍被旧进程占着:
sudo lsof -iTCP:3000 -sTCP:LISTEN
sudo kill -TERM <pid>
# 再启动新进程
把这几条写进团队 runbook,比每次临时搜命令稳得多。
小提示
- 多数占用信息需要 root;权限不够时输出会缺字段,别误判成「没人占用」。
- 容器里看到的 PID 是命名空间内的,宿主机要用容器运行时的映射再查。
- 和
ss搭配:先ss定位端口,再lsof -i/lsof -p追到具体文件与工作目录。 - 输出列很多时,可用
lsof -nP跳过主机名与端口名反查,速度更快,也更适合脚本解析。
日常运维里,把 lsof 当成「占用显微镜」即可:定位清晰,改动能落到具体进程,少做无意义的重启。
- 点赞
- 收藏
- 关注作者
评论(0)