🔌 端口占用排查与进程清理命令
✨ 启动服务时看到 address already in use、port is already allocated、EADDRINUSE,通常就是端口已经被某个进程占用了。处理思路很固定:先查端口对应的 PID,再确认进程名,最后结束进程。
🧠 先记住一句话
端口本身不能被“杀掉”,真正要结束的是占用这个端口的进程。
常见流程:
1
| 端口号 -> PID -> 进程名 -> kill / taskkill / Stop-Process
|
比如你要处理 8080 端口,就先查谁在监听 8080,再结束对应 PID。
⚡ 最快速查
Windows PowerShell
1 2 3
| Get-NetTCPConnection -LocalPort 8080 | Select-Object LocalAddress, LocalPort, State, OwningProcess Get-Process -Id <PID> Stop-Process -Id <PID> -Force
|
Windows CMD
1 2 3
| netstat -ano | findstr :8080 tasklist /FI "PID eq <PID>" taskkill /PID <PID> /F
|
macOS / Linux
1 2
| lsof -nP -iTCP:8080 -sTCP:LISTEN kill -15 <PID>
|
强制结束:
🪟 Windows PowerShell
PowerShell 里推荐优先用 Get-NetTCPConnection,输出结构化,适合继续管道处理。
查端口对应 PID
1
| Get-NetTCPConnection -LocalPort 8080
|
只看关键字段:
1 2
| Get-NetTCPConnection -LocalPort 8080 | Select-Object LocalAddress, LocalPort, State, OwningProcess
|
OwningProcess 就是 PID。
如果只想查正在监听的进程:
1 2
| Get-NetTCPConnection -LocalPort 8080 -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess
|
根据 PID 查看进程名
例如:
结束进程
温和结束:
强制结束:
1
| Stop-Process -Id <PID> -Force
|
一行命令结束占用端口的进程
1 2 3
| Get-NetTCPConnection -LocalPort 8080 -State Listen | Select-Object -ExpandProperty OwningProcess -Unique | ForEach-Object { Stop-Process -Id $_ -Force }
|
[!warning]
一行 kill 命令很爽,但最好先用 Get-Process -Id <PID> 看一下是不是你自己的开发服务。不要随手结束数据库、Docker、系统服务。
🪟 Windows CMD
CMD 里最常用的是 netstat + findstr + taskkill。
查端口对应 PID
1
| netstat -ano | findstr :8080
|
你会看到类似:
1
| TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 12345
|
最后一列 12345 就是 PID。
如果只想找监听状态:
1
| netstat -ano | findstr :8080 | findstr LISTENING
|
根据 PID 查看进程名
1
| tasklist /FI "PID eq 12345"
|
结束进程
一行命令结束占用端口的进程
在 CMD 里直接执行:
1
| for /f "tokens=5" %a in ('netstat -ano ^| findstr :8080 ^| findstr LISTENING') do taskkill /F /PID %a
|
如果写在 .bat 文件里,变量要写成 `a in (‘netstat -ano ^| findstr :8080 ^| findstr LISTENING’) do taskkill /F /PID %%a
1 2 3 4 5 6 7 8 9 10 11
| ---
## 🍎 macOS
macOS 上最常用的是 `lsof`。
### 查端口对应 PID
```bash lsof -nP -iTCP:8080 -sTCP:LISTEN
|
参数含义:
-n: 不解析主机名,速度更快
-P: 不解析端口名,直接显示端口号
-iTCP:8080: 查 TCP 8080 端口
-sTCP:LISTEN: 只看监听状态
只输出 PID:
查看进程信息
1
| ps -p <PID> -o pid,ppid,user,comm,args
|
结束进程
优先温和结束:
还没退出时再强制结束:
一行命令结束占用端口的进程
1
| lsof -ti tcp:8080 | xargs kill -15
|
强制结束:
1
| lsof -ti tcp:8080 | xargs kill -9
|
如果端口没有进程,xargs 可能仍然执行 kill。更稳一点可以这样:
1 2
| pid=$(lsof -ti tcp:8080) [ -n "$pid" ] && kill -15 $pid
|
🐧 Linux
Linux 上常见选择有 ss、lsof、fuser。其中 ss 通常是系统自带的新工具,lsof 更直观,fuser 适合快速清理。
用 ss 查端口
1
| sudo ss -ltnp 'sport = :8080'
|
或者:
1
| sudo ss -ltnp | grep ':8080'
|
输出里通常会看到类似:
1
| users:(("node",pid=12345,fd=21))
|
这里的 12345 就是 PID。
用 lsof 查端口
1
| sudo lsof -nP -iTCP:8080 -sTCP:LISTEN
|
只输出 PID:
查看进程信息
1
| ps -p <PID> -o pid,ppid,user,comm,args
|
结束进程
强制结束:
如果不是当前用户的进程,需要加 sudo:
用 fuser 直接释放端口
查看端口:
直接结束占用这个 TCP 端口的进程:
fuser -k 很直接,适合你确认这个端口就是开发服务时使用。
🐚 Bash / Zsh
macOS 和大多数 Linux 发行版都可以用类似写法。
查端口
1 2
| PORT=8080 lsof -nP -iTCP:$PORT -sTCP:LISTEN
|
结束端口进程
1 2 3
| PORT=8080 PID=$(lsof -ti tcp:$PORT) [ -n "$PID" ] && kill -15 $PID
|
强制结束:
1 2 3
| PORT=8080 PID=$(lsof -ti tcp:$PORT) [ -n "$PID" ] && kill -9 $PID
|
封装成函数
可以放到 ~/.zshrc 或 ~/.bashrc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| killport() { local port="$1" if [ -z "$port" ]; then echo "Usage: killport <port>" return 1 fi
local pid pid=$(lsof -ti tcp:"$port") if [ -z "$pid" ]; then echo "No process is listening on port $port" return 0 fi
echo "Killing port $port, PID: $pid" kill -15 $pid }
|
使用:
🐟 Fish Shell
Fish 的变量写法和 Bash/Zsh 不一样。
查端口
1 2
| set port 8080 lsof -nP -iTCP:$port -sTCP:LISTEN
|
结束端口进程
1 2 3
| set port 8080 set pid (lsof -ti tcp:$port) test -n "$pid"; and kill -15 $pid
|
强制结束:
1 2 3
| set port 8080 set pid (lsof -ti tcp:$port) test -n "$pid"; and kill -9 $pid
|
封装成函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function killport set port $argv[1] if test -z "$port" echo "Usage: killport <port>" return 1 end
set pid (lsof -ti tcp:$port) if test -z "$pid" echo "No process is listening on port $port" return 0 end
echo "Killing port $port, PID: $pid" kill -15 $pid end
|
保存为永久函数:
🧩 Git Bash / WSL 怎么办
Git Bash
Git Bash 跑在 Windows 上,所以端口真正属于 Windows 系统。最稳的是直接调用 Windows 命令:
1 2
| netstat -ano | findstr :8080 taskkill //PID 12345 //F
|
有些 Git Bash 环境会把 /PID 当路径处理,所以可以写成 //PID 和 //F。
WSL
如果服务是在 WSL 里启动的,优先在 WSL 里用 Linux 命令:
1 2
| sudo lsof -nP -iTCP:8080 -sTCP:LISTEN sudo kill -15 <PID>
|
如果服务是在 Windows 里启动的,就回到 PowerShell 或 CMD 查。
🧯 常见场景
Vite / React / Vue 提示端口被占用
一般是上一次 dev server 没退干净。
1
| lsof -ti tcp:5173 | xargs kill -15
|
Windows PowerShell:
1 2 3
| Get-NetTCPConnection -LocalPort 5173 -State Listen | Select-Object -ExpandProperty OwningProcess -Unique | ForEach-Object { Stop-Process -Id $_ -Force }
|
Node 服务提示 EADDRINUSE
先查:
1
| lsof -nP -iTCP:3000 -sTCP:LISTEN
|
再结束:
Windows CMD:
1 2
| netstat -ano | findstr :3000 taskkill /PID <PID> /F
|
Docker 提示 port is already allocated
先确认宿主机端口是谁占了:
1
| lsof -nP -iTCP:8080 -sTCP:LISTEN
|
如果是 Docker 容器占用,查看容器:
1
| docker ps --filter publish=8080
|
停止容器:
1
| docker stop <container_id>
|
✅ 建议习惯
- 先查端口,不要直接 kill。
- 先看进程名,确认是不是自己的开发服务。
- 优先用
kill -15 或 Stop-Process 温和结束。
- 进程无响应时再用
kill -9、taskkill /F、Stop-Process -Force。
- 如果总是同一个端口冲突,可以给开发服务换端口,或者检查是否有后台自启动服务。
🧾 命令对照表
| 系统 / Shell |
查端口 |
查进程 |
结束进程 |
| PowerShell |
Get-NetTCPConnection -LocalPort 8080 |
Get-Process -Id <PID> |
Stop-Process -Id <PID> -Force |
| CMD |
`netstat -ano \ |
findstr :8080` |
tasklist /FI "PID eq <PID>" |
taskkill /PID <PID> /F |
| macOS |
lsof -nP -iTCP:8080 -sTCP:LISTEN |
ps -p <PID> -o pid,ppid,user,comm,args |
kill -15 <PID> |
| Linux |
sudo ss -ltnp 'sport = :8080' |
ps -p <PID> -o pid,ppid,user,comm,args |
sudo kill -15 <PID> |
| Bash / Zsh |
lsof -ti tcp:8080 |
ps -p <PID> -o comm,args |
kill -15 <PID> |
| Fish |
lsof -ti tcp:$port |
ps -p $pid -o comm,args |
kill -15 $pid |
总结
端口占用排查没有玄学,核心就是三步:
Windows 记住 netstat / taskkill 或 Get-NetTCPConnection / Stop-Process,macOS 和 Linux 记住 lsof / kill,Linux 服务器上再补一个 ss 和 fuser。这些命令够覆盖绝大多数开发场景。