用 lsof 指令尋找佔用通訊埠的 Process

Posted on  Dec 19, 2022  in  Unix-like 命令列教學  by  Amo Chen  ‐ 2 min read

最近在開發 Next.js 相關的應用程式,無腦寫了無窮迴圈造成 dev server 關不掉,導致重啟 dev server 時會顯示以下警告訊息,該訊息顯示通訊埠(port) 3000 正在被其他 process 佔用:

warn  - Port 3000 is in use, trying 3001 instead.

本文紀錄如何找到佔用 port 的 Process Id 並且停止其運作。

本文環境

  • macOS

lsof 指令

lsof 指令是 macOS 與 Linux 都擁有的內建指令,用途為顯示開啟的檔案列表,由於 Unix-like 的作業系統設計哲學,一切都可視為檔案,所以連 service 所開啟的網路服務也是一個檔案,因此可用 lsof 列出。

如果要找出佔用 port 3000 的 TCP 服務,可以使用以下指令:

$ lsof -Pi tcp:3000 | grep LISTEN

上述指令結果如下,可以看到 PID 88627 正在監聽(LISTEN) port 3000:

COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
node    88627 user.name   23u  IPv6 0xe2b29f4b29788c6f      0t0  TCP *:3000 (LISTEN)

前述指令 -P 參數會將 port 的名字轉成數字顯示,否則就會以 port 名稱顯示,例如 3000 可能會顯示成 hbci (Home Banking Computer Interface), 如果不知道 port 名稱的人,會很有可能以為指令執行結果有問題,所以加上 -P 比較好。

-i 參數則是用以過濾網路相關的設定,其格式如下所示:

[46][protocol][@hostname|hostaddr][:service|port]

[46] 代表要濾出 IPv4 還是 IPv6, 如果只想顯示 IPv6 列表的話,可以指定 -i 4

[protocol] 則代表只顯示 TCP 或是 UDP 的列表,如果只想顯示 TCP 的列表,可以使用 -i tcp , 也可以進一步使用 -i 4tcp 代表只顯示使用 IPv4 TCP 的列表。

[@hostname|hostaddr] 則可以用 IP 位址或 hostname 進行過濾,例如 -i @localhost 代表指顯示 listen 在 localhost 的列表,也可以寫成 -i @127.0.0.1

[:service|port] 則是用 port 或 port name 進行過濾(port name 可以在 /etc/services 中找到),例如前述指令只顯示 3000 port 的列表可表示為 -i :3000

這 4 種格式可以視需求搭配使用,例如指顯示執行在 0.0.0.0:3000 的 IPv4 TCP 列表,可以表示為 -i [email protected]:3000

找到之後,可以使用以下指令強制停止該 Process, 其中 88627 就是要被停止執行的 Process Id:

$ kill -9 88627

以上就是用 lsof 指令找到佔用通訊埠的 Process Id 的簡單介紹。

Happy Coding!

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!