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,代表作業系統拒絕了 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)

要終止的是 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,由核心立即強制執行,處理程序完全沒有機會收拾善後,因此:

先送 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 App
4200Angular CLI
5000, 7000AirPlay 接收器(ControlCenter)、Flask 預設值
5173, 4173Vite 開發伺服器、Vite preview
8000Django、python3 -m http.server
8080Tomcat、Spring Boot、各種 proxy
8888Jupyter
5432, 3306, 6379, 27017PostgreSQL、MySQL、Redis、MongoDB
11434Ollama

同一個 lsof 指令適用於以上任何一個:把 3000 換成對應的連接埠號碼即可。

為什麼 macOS 的連接埠 5000 或 7000 被佔用?

從 macOS Monterey 開始,AirPlay 接收器會監聽連接埠 5000 和 7000,lsof 顯示的擁有者是 ControlCenter。這就是為什麼在什麼都沒開的 Mac 上,全新的 Flask App 也會出現「Address already in use」。不要終止 ControlCenter,macOS 會把它重新啟動。請改用以下其中一種做法:

下次怎麼避免連接埠衝突?

從選單列查出連接埠被誰佔用

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,並提供七天試用。

下載 WTMemory

常見問題

怎麼用一行指令終止佔用連接埠 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 改用其他連接埠。

相關教學

完整的 WTMemory 使用說明與授權協助