WTMemory 指南

Mac 端口 3000 被占用:查找并结束占用进程

2026年10月13日更新

要在 Mac 上释放端口 3000,先运行 lsof -nP -iTCP:3000 -sTCP:LISTEN 看是哪个进程在监听,再用 kill <PID> 结束它。只有进程不理会普通信号时才用 kill -9。罪魁祸首通常是之前没关掉的开发服务器(Node、Vite、Next.js、Rails、Python)。

如果你不想敲命令,更想直接看一份监听端口列表,免费的 WTMemory 菜单栏 App会把端口和对应的进程一起列出来。文末会详细介绍;下面的终端方法在任何一台 Mac 上都适用。

“EADDRINUSE: address already in use :::3000” 是什么意思?

同一个 TCP 端口和地址同一时间只能有一个进程监听。当 Node 输出 Error: listen EADDRINUSE: address already in use :::3000,或者 Rails 提示 Address already in use - bind(2) for "127.0.0.1" port 3000 时,说明系统拒绝了绑定,因为已经有别的进程占着这个端口。你的新服务器本身没问题。你需要找到并停止旧的监听进程,或者换一个端口启动。

Mac 上怎么查看端口 3000 被谁占用?

macOS 自带 lsof(list open files,列出打开的文件),它也能列出网络套接字:

lsof -nP -iTCP:3000 -sTCP:LISTEN

典型输出:

COMMAND   PID  USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
node    48213  you    23u  IPv6  0x...       0t0  TCP *:3000 (LISTEN)

要结束的就是 PID 这一列。COMMAND 会被截断为九个字符,想看包括项目路径在内的完整命令行,运行 ps -p 48213 -o pid,ppid,etime,command。

一次列出这台 Mac 上所有正在监听的 TCP 端口:

lsof -nP -iTCP -sTCP:LISTEN

lsof 只显示你有权限查看的进程。如果端口被占用但 lsof 什么都没输出,说明监听进程属于其他用户或 root:加上 sudo 再运行一次。

怎么结束占用端口 3000 的进程?

kill 48213

再运行一次 lsof 命令。没有输出就说明端口已经空出来了。写成一行:

lsof -ti tcp:3000 -sTCP:LISTEN | xargs kill

-t 只输出 PID,由 xargs 交给 kill。macOS 上的 BSD xargs 在没有输入时不会执行命令,所以端口本来就空闲时运行它也不会出问题。

务必保留 -sTCP:LISTEN 过滤条件。网上流传的 lsof -ti :3000 | xargs kill 还会匹配所有连接到端口 3000 的客户端,其中通常就有你打开着 localhost:3000 的浏览器标签页。不加过滤,你可能会把 Chrome 或 Safari 和服务器一起关掉。

kill 和 kill -9:该用哪个?

普通的 kill 发送 SIGTERM,礼貌地请进程退出。Node、Vite、Next.js、Rails 和大多数服务器都会捕获它,关闭套接字、写完日志并停止子进程。kill -9 发送 SIGKILL,由内核立即强制执行。进程没有机会做清理,因此:

先发 kill,等两三秒,用 lsof 检查,确实不行再升级到 kill -9。

为什么关了终端,服务器还在跑?

关闭终端窗口一般会挂断 shell 及其作业,但很多情况下进程能活下来:

怎么按名称找出残留的开发服务器?

当残留的服务器有好几个时,按名称列出它们,同时显示父进程 PID 和运行时长:

ps -axo pid,ppid,etime,command | grep -E 'node|vite|next|webpack|rails|python' | grep -v grep

PPID 为 1 说明进程成了孤儿,被 launchd 收养。ETIME 很长(好几天,或者没开终端却跑了好几个小时)也是一个信号。pgrep -fl vite 给出的列表更简短。你可以用 pkill -f "next dev" 按模式结束进程,但请先用 pgrep -fl "next dev" 看看会匹配到什么,因为 -f 会在完整命令行的任意位置匹配。

如果是 Docker 占着端口怎么办?

如果 lsof 显示的是 Docker 进程(例如 com.docker.backend),说明是某个容器发布了这个端口。不要结束 Docker 进程,否则所有容器都会停掉。找到那个容器并停止它:

docker ps --filter "publish=3000"
docker stop <container>

Mac 上常见的开发端口

端口通常的占用者
3000Next.js、Create React App、Nuxt、Rails、很多 Express 应用
4200Angular CLI
5000, 7000AirPlay 接收器(ControlCenter)、Flask 默认端口
5173, 4173Vite 开发服务器、Vite 预览
8000Django、python3 -m http.server
8080Tomcat、Spring Boot、各种代理
8888Jupyter
5432, 3306, 6379, 27017PostgreSQL、MySQL、Redis、MongoDB
11434Ollama

同样的 lsof 命令对这些端口都适用:把 3000 换成对应的端口号即可。

macOS 上为什么端口 5000 或 7000 被占用?

从 macOS Monterey 开始,AirPlay 接收器会监听 5000 和 7000 端口,lsof 显示的占用者是 ControlCenter。这就是为什么在一台什么都没运行的 Mac 上,新建的 Flask 应用也会报 “Address already in use”。不要结束 ControlCenter,macOS 会重新启动它。你可以:

以后怎么避免端口冲突?

在菜单栏里查看端口被谁占用

WTMemory 是一款原生 macOS 菜单栏 App,支持 macOS 12 及以上版本,兼容 Apple 芯片和 Intel 机型。在菜单中选择 Find What's Using a Port(查找端口占用),即可看到所有 TCP 监听端点及其背后的进程;或者打开 Running Apps(运行中的 App),查看每个开发进程的 PID、可执行文件位置、内存和 CPU 占用。查看功能免费。

结束进程属于 Pro 功能,执行前你会先核对并确认。停止一个监听进程会结束整个进程,而不只是释放一个端口;WTMemory 不会把进程标记为“已废弃”或“可以安全结束”,由你自己决定。用锁定按钮保护的应用永远不会被退出。Pro 一次性付费 $9 USD,最多可用于三台 Mac,并提供七天试用。

下载 WTMemory

常见问题

怎样用一条命令结束占用端口 3000 的进程?

运行 lsof -ti tcp:3000 -sTCP:LISTEN | xargs kill。-sTCP:LISTEN 这个过滤条件很关键:少了它,lsof 还会返回连接到端口 3000 的客户端(比如你的浏览器),它们也会被一起结束。

kill -9 不好吗?

它是最后手段。SIGKILL 会立即结束进程,进程来不及写完数据、删除锁文件或停止子进程。先用普通的 kill,等几秒再说。

为什么进程结束后又自己起来了?

有东西在重启它:通过 launchd 运行的 Homebrew 服务、pm2、nodemon、文件监听工具,或者设置了重启策略的 Docker 容器。请改用对应工具来停止,比如 brew services stop 或 docker stop。

查看端口占用需要 sudo 吗?

只有进程属于其他用户或 root 时才需要。如果 lsof 什么都没显示但端口仍被占用,就加上 sudo 再运行同样的命令。

Mac 上什么都没运行,为什么端口 5000 被占用?

从 macOS Monterey 开始,AirPlay 接收器会通过 ControlCenter 进程监听 5000 和 7000 端口。在系统设置中关闭 AirPlay 接收器,或者让你的应用换个端口运行。

相关指南

WTMemory 完整使用指南与许可证帮助