4. macOS 端口排查:lsof、netstat 与 Activity Monitor
说实话,macOS 上的端口排查,跟 Linux 有点像,但又有不少坑。我刚开始从 Linux 切到 macOS 做开发时,第一反应就是——netstat 怎么参数不一样了?后来才慢慢摸清门道。
这一节,我带你过一遍 macOS 上最实用的几个工具:lsof -i、netstat -an,还有图形化的 Activity Monitor。最后再聊聊那个让人头疼的 "port already in use" 怎么解决。
4.1 lsof -i:我的首选武器
我个人习惯,排查端口问题第一个想到的就是 lsof。它全称是 "list open files",在 Unix 世界里,一切皆文件,网络连接也不例外。
最常用的命令就这一条:
sudo lsof -i :端口号
比如,我想看看 8080 端口被谁占了:
sudo lsof -i :8080
输出大概长这样:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 12345 zhangsan 123u IPv6 0x123456789abcdef 0t0 TCP *:8080 (LISTEN)
关键信息一目了然:
- COMMAND:哪个程序占的(这里是 java)
- PID:进程 ID(12345)
- USER:哪个用户跑的
- NAME:具体监听地址和状态(LISTEN 表示正在监听)
如果想看所有正在监听的端口,可以这样:
sudo lsof -i -P | grep LISTEN
这里的 -P 参数很关键——它让 lsof 不把端口号解析成服务名。你想想看,显示 "8080" 比显示 "http-alt" 直观多了吧?
4.2 netstat -an:老牌工具,参数有坑
macOS 自带的 netstat 跟 Linux 版不太一样。我第一次在 Mac 上敲 netstat -tlnp,结果报错——根本没这个参数。
macOS 上正确的用法是:
netstat -an | grep LISTEN
或者想看某个特定端口:
netstat -an | grep 8080
输出示例:
tcp4 0 0 *.8080 *.* LISTEN
tcp6 0 0 *.8080 *.* LISTEN
这里 tcp4 和 tcp6 分别代表 IPv4 和 IPv6 的监听。有时候你会发现同一个端口出现两次,别慌,这是正常的——一个应用同时监听了两种协议。
-p 参数来显示进程名。想看哪个进程占用了端口,还得靠 lsof。所以我的习惯是:快速扫一眼用 netstat,深挖用 lsof。
4.3 Activity Monitor:图形化排查
有些时候,你不想敲命令,或者你正在给一个不太熟悉命令行的同事远程指导——这时候 Activity Monitor(活动监视器)就派上用场了。
打开方式:
- 在 Launchpad 里搜 "活动监视器"
- 或者用 Spotlight(Cmd+Space)直接搜
怎么用它查端口?嗯,这里有个小技巧——它本身不直接显示端口号。但你可以这样:
- 打开 Activity Monitor
- 在搜索框里输入进程名(比如 java、python)
- 双击进程,点 "打开文件和端口"
- 在列表里找
TCP类型的条目,端口号就在后面
这个方法比较笨,但胜在直观。我记得有一次帮一个前端同事排查问题,他死活记不住 lsof 命令,我就让他用 Activity Monitor 找到了占端口的 Node.js 进程。
4.4 解决 "port already in use"
这个错误,我相信每个人都遇到过。你启动服务,啪,报错:
Error: listen EADDRINUSE: address already in use :::8080
为什么会这样?说白了,就是你要用的端口已经被别的进程占用了。解决思路无非两条:
- 杀掉占用的进程
- 换一个端口
先查出来是谁占的:
sudo lsof -i :8080
拿到 PID 之后,直接杀掉:
sudo kill -9 12345
这里 -9 是强制杀死,有时候进程比较顽固,普通 kill 杀不掉。
ps aux | grep PID 确认一下。
如果你不想杀进程,那就换个端口启动。比如把 8080 改成 8081:
# 以 Node.js 为例
PORT=8081 npm start
或者改配置文件里的 server.port 之类的参数。
4.5 知识体系总览
下面这张图,帮你把 macOS 端口排查的整个流程串起来:
4.6 实战场景对比
不同场景下,选哪个工具更顺手?我整理了一个表格:
| 场景 | 推荐工具 | 原因 |
|---|---|---|
| 快速查某个端口被谁占 | lsof -i :端口 |
一行命令,进程名、PID、状态全出来 |
| 看系统所有监听端口 | netstat -an | grep LISTEN |
输出简洁,适合批量扫描 |
| 不熟悉命令行的同事排查 | Activity Monitor | 图形界面,搜索进程名即可 |
| 确认进程身份后再杀 | lsof + ps aux |
先查清楚,避免误杀 |
好了,macOS 上的端口排查就这些。记住一个核心思路:先查谁占的,再决定是杀还是换。别一上来就 kill -9,搞不好就把别人的服务干掉了。