lsof 与 fuser 是什么
lsof -i 列出进程打开的套接字,直接给出占用端口的 PID、用户与可执行文件;fuser -n tcp 只吐 PID,适合脚本里取号。两者都是从 /proc/<pid>/fd 反查套接字 inode,因此只能看到被进程持有的连接:处于 TIME-WAIT 的残留套接字没有属主进程,查不到是正常的,不要因此认定工具失效。
基本信息
| 适用平台 | Linux(macOS 自带 lsof);Windows 用 netstat -ano |
|---|---|
| 标准语法 | lsof -i :8080 / fuser -n tcp 8080 |
| 权限要求 | 查其他用户的进程需 root,普通用户只能看到自己的进程 |
| 安装依赖 | lsof 非最小化安装自带:Debian/Ubuntu apt install lsof,RHEL 系 yum install lsof |
| 无 lsof 时的替代 | ss -tlnp 'sport = :8080' |
典型使用场景
- 服务启动报 bind 失败,先确认端口到底被谁占着
- 安全巡检:核对对外监听端口的属主是否都在预期清单内
- 容器环境里宿主机端口被 docker-proxy 或 kube-proxy 占用,判断能否改端口
- 查找已被删除但仍占用磁盘空间的文件(lsof | grep deleted)
- 核对进程真实性:用 /proc/<pid>/exe 与 /proc/<pid>/cmdline 看可执行文件与启动参数
定位占用者
定位占用者
lsof -i :8080 # 列出该端口所有相关套接字
lsof -iTCP:8080 -sTCP:LISTEN # 只保留 LISTEN 行,过滤掉客户端连接
lsof -i :8080 -P -n # 关闭端口名/服务名解析,输出更快更稳定
fuser -n tcp 8080 # 只输出 PID,便于脚本取号
ss -tlnp 'sport = :8080' # 未安装 lsof 时的替代写法
ls -l /proc/<PID>/exe # 该 PID 对应的可执行文件绝对路径输出逐列读法
| 列 | 含义 | 判读要点 |
|---|---|---|
| COMMAND | 进程名,默认截断 15 字符 | 名字被截断时用 ps -p <PID> -o cmd= 看完整命令行 |
| PID | 进程号 | 同一进程可能有多行,对应多个套接字 |
| USER | 进程属主 | 非 root 用户监听公网端口时重点核实来源 |
| TYPE | 套接字类型(IPv4/IPv6) | IPv4 与 IPv6 各一行属双栈监听,正常现象 |
| NAME | 本地地址:端口 与状态 | 带 (LISTEN) 才是监听方;带 -> 的是已建立的客户端连接 |
TIME-WAIT 套接字没有归属进程,lsof/fuser 都查不到,要用 ss -tan state time-wait 'sport = :8080' 查。重启服务后仍报占用,通常是旧进程没退干净,而不是 TIME-WAIT 本身。
在容器环境里宿主机看到的监听者可能是 docker-proxy 或 kube-proxy,属正常转发进程;先 docker ps 或 kubectl get svc 对照,再决定是否改配置。