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,代表作業系統拒絕了 bind,因為已經有東西佔著這個連接埠。你的新伺服器本身沒問題,你要做的是找出並停止舊的監聽者,或改用其他連接埠啟動。
怎麼查出 Mac 上連接埠 3000 被誰佔用?
macOS 內建 lsof(list open files,列出開啟的檔案),它也會列出網路 socket:
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)
-iTCP:3000只顯示連接埠 3000 上的 TCP socket。-sTCP:LISTEN只顯示監聽中的 socket,不包含連進來的用戶端。-n和-P會略過 DNS 與連接埠名稱查詢,讓 lsof 快很多。
要終止的是 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 和大多數伺服器都會接住這個訊號,關閉 socket、寫完日誌並停止子處理程序。kill -9 送出的是 SIGKILL,由核心立即強制執行,處理程序完全沒有機會收拾善後,因此:
- 子處理程序(worker、監看工具、打包工具)可能變成孤兒繼續執行,並持續佔用其他連接埠。
- 鎖定檔、PID 檔和暫存檔會留下來,有些工具在你刪掉它們之前都不肯啟動。
- PostgreSQL 或 MySQL 這類資料庫下次啟動時必須執行當機復原。請改用它們自己的工具停止,例如
brew services stop postgresql@16。
先送 kill,等兩三秒,用 lsof 確認,真的不行再升級成 kill -9。
為什麼關掉終端機後伺服器還在跑?
關閉終端機視窗通常會掛斷 shell 和它的工作,但很多情況下程式還是會活下來:
- 按了 Ctrl+Z 而不是 Ctrl+C。Ctrl+Z 會暫停伺服器,而被暫停的處理程序仍然佔著連接埠。執行
jobs,再用fg叫回來後按 Ctrl+C。 - 孤兒子處理程序。
npm run dev會啟動一個 shell,再由它啟動node。如果父處理程序突然結束,子處理程序可能被重新掛到launchd(PID 1)底下,繼續提供服務。 - 編輯器的終端機與工作。VS Code、Cursor 和 JetBrains IDE 在視窗關閉或當掉後,整合式終端機和背景工作仍可能繼續執行。
- tmux、screen、
nohup,或&搭配disown。這些本來就是設計來比終端機活得更久的。 - 監管程式。
brew services(launchd)、pm2、nodemon 和 Docker 的重啟策略,會在處理程序被終止後立刻用新的 PID 把它帶回來。
怎麼依名稱找出殘留的開發伺服器?
有好幾個殘留的伺服器時,可以依名稱列出它們,連同父處理程序 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 上常見的開發用連接埠
| 連接埠 | 常見的使用者 |
|---|---|
| 3000 | Next.js、Create React App、Nuxt、Rails、許多 Express App |
| 4200 | Angular CLI |
| 5000, 7000 | AirPlay 接收器(ControlCenter)、Flask 預設值 |
| 5173, 4173 | Vite 開發伺服器、Vite preview |
| 8000 | Django、python3 -m http.server |
| 8080 | Tomcat、Spring Boot、各種 proxy |
| 8888 | Jupyter |
| 5432, 3306, 6379, 27017 | PostgreSQL、MySQL、Redis、MongoDB |
| 11434 | Ollama |
同一個 lsof 指令適用於以上任何一個:把 3000 換成對應的連接埠號碼即可。
為什麼 macOS 的連接埠 5000 或 7000 被佔用?
從 macOS Monterey 開始,AirPlay 接收器會監聽連接埠 5000 和 7000,lsof 顯示的擁有者是 ControlCenter。這就是為什麼在什麼都沒開的 Mac 上,全新的 Flask App 也會出現「Address already in use」。不要終止 ControlCenter,macOS 會把它重新啟動。請改用以下其中一種做法:
- 在「系統設定」>「一般」>「AirDrop 與接力」中關閉 AirPlay 接收器(Monterey 則是「系統偏好設定」>「共享」),或
- 讓你的 App 改用其他連接埠,例如
flask run --port 5001。
下次怎麼避免連接埠衝突?
- 用 Ctrl+C 而不是 Ctrl+Z 停止伺服器,關閉終端機前先用
jobs檢查一下。 - 需要同時跑兩個專案時,換一個連接埠:
PORT=3001 npm start、next dev -p 3001或vite --port 5174。 - Vite 會自動改用下一個空著的連接埠。如果你寧願它直接失敗、好讓你發現殘留的伺服器,請加上
--strictPort。
從選單列查出連接埠被誰佔用
WTMemory 是原生的 macOS 選單列 App,支援 macOS 12 以上版本,Apple Silicon 與 Intel 皆可使用。從選單中選擇 Find What's Using a Port(找出佔用連接埠的程式),就能看到 TCP 監聽端點和背後的處理程序;或打開 Running Apps(執行中的 App),查看每個開發用處理程序的 PID、執行檔位置、記憶體與 CPU。檢視功能免費。
停止處理程序屬於 Pro 功能,而且你會先檢視並確認。停止某個監聽者會停掉整個處理程序,而不只是一個連接埠;WTMemory 也不會替處理程序貼上「已被遺棄」或「可以安全停止」的標籤:由你決定。用鎖定控制項保護的 App 永遠不會被結束。Pro 一次付清 $9 USD,最多可用於三台 Mac,並提供七天試用。
常見問題
怎麼用一行指令終止佔用連接埠 3000 的程式?
執行 lsof -ti tcp:3000 -sTCP:LISTEN | xargs kill。-sTCP:LISTEN 這個過濾條件很重要:少了它,lsof 也會列出連到連接埠 3000 的用戶端(例如你的瀏覽器),結果連它們一起終止。
kill -9 不好嗎?
它是最後手段。SIGKILL 會立刻結束處理程序,完全沒有機會寫入未完成的資料、移除鎖定檔或停止子處理程序。請先用一般的 kill,等幾秒再說。
為什麼處理程序被終止後又跑回來?
有東西在重新啟動它:透過 launchd 執行的 Homebrew services、pm2、nodemon、檔案監看工具,或設有重啟策略的 Docker 容器。請改用那個工具來停止它,例如 brew services stop 或 docker stop。
查看連接埠被誰佔用需要 sudo 嗎?
只有處理程序屬於其他使用者或 root 時才需要。如果 lsof 什麼都沒列出、連接埠卻仍被佔用,就用 sudo 再執行同一個指令。
我明明沒開任何東西,為什麼 Mac 的連接埠 5000 被佔用?
從 macOS Monterey 開始,AirPlay 接收器會透過 ControlCenter 處理程序監聽連接埠 5000 和 7000。請在「系統設定」中關閉 AirPlay 接收器,或讓你的 App 改用其他連接埠。