用 lsof -i :8080 查端口占用,需加 sudo 才可见全部进程;lsof /path 查文件被谁打开;lsof -p PID 查指定进程的文件和端口;卡顿时加 -n -N 跳过解析与 NFS 扫描。

查哪个进程占用了某个端口(比如 8080)
直接用 lsof -i :8080 就能列出所有监听或连接该端口的进程。注意:普通用户只能看到自己启动的进程,看不到 root 或其他用户的;想看全,得加 sudo。
常见错误是只输 lsof -i :8080 却没权限,结果返回空——不是没占用,是看不见。这时候补上 sudo lsof -i :8080 才算完整。
-
-i表示按网络连接筛选,后面跟协议+端口,比如:22、tcp:443、udp:53 - 如果只想看监听(LISTEN)状态,加
-sTCP:LISTEN,避免混入 ESTABLISHED 连接 - 输出里
PID列就是进程号,COMMAND是程序名,USER是启动者,三者缺一不可定位
查某个文件或目录被哪些进程打开
用 lsof /path/to/file 或 lsof /var/log。路径必须写全,不能用通配符(lsof *.log 无效),也不能省略前导斜杠(lsof log 查不到任何东西)。
典型场景:删不掉文件,提示 Device or resource busy;或者 umount 失败,其实都是因为有进程正打开着里面某个文件或子目录。
- 加
+D可递归查整个目录树,但性能差、耗时长,慎用:lsof +D /tmp - 加
-t只输出 PID,方便配合kill,比如kill $(lsof -t /var/run/nginx.pid) - 注意硬链接和符号链接:
lsof显示的是实际打开的 inode,不是 symlink 路径本身
查某个进程打开了哪些文件和端口
用 lsof -p 1234,其中 1234 是目标进程的 PID。比 ps 或 cat /proc/1234/fd 更直观,尤其对网络连接。
容易忽略的是:有些进程会 fork 出子进程并继承 fd,但 lsof -p 默认只查指定 PID 的主线程,不包含子线程或子进程。真要全覆盖,得加 -R(递归查子进程)——但多数时候不需要,先看主线程就够了。
-
-a可组合多个条件,比如lsof -a -p 1234 -i只显示该进程的网络连接 - 输出中
TXT类型表示可执行文件(即程序本体),DEL表示已删除但仍被打开的文件,这类文件磁盘空间不会释放 - 如果进程已退出但还有残留 fd(比如僵尸句柄),
lsof -p不会显示,得靠/proc手动排查
为什么 lsof 没反应或卡住?
最常见原因是它在遍历 NFS 挂载点、或某些异常挂载的文件系统(如 cifs、fuse),导致内核调用阻塞。这不是 bug,是设计使然:lsof 需要读取每个进程的 /proc/PID/fd/ 目录,而某些远程文件系统响应慢或无响应。
解决方法不是等,而是绕开:
- 加
-n跳过 DNS 反解(避免卡在 hostname 查询) - 加
-N跳过 NFS 文件系统扫描(NFS 相关条目直接忽略) - 用
lsof -P -n组合,既不解析端口名(如把 22 显示成 ssh),也不解析 IP 主机名,提速明显 - 如果连
lsof -v都卡,说明/proc本身可能异常,优先检查mount | grep proc
真正麻烦的从来不是命令怎么写,而是你不确定该查进程、查端口,还是查文件路径——这三个方向对应完全不同的参数组合,错一个就白等几秒。多试两次 lsof -i 和 lsof -p,比背参数有用。

















