按进程、端口或文件反查 macOS 上谁打开了它。
lsof 列出进程打开的文件描述符,包括普通文件、目录、管道、套接字和设备。网络排障最常用的是把端口映射到 PID:lsof -nP -iTCP:8080、lsof -nP -iTCP -sTCP:LISTEN。它也能回答“这个外接盘为什么卸不掉”“谁占着日志文件”,比 netstat 多了进程维度。
-n 禁止地址反解,-P 禁止端口名转换,两者几乎应该常带,否则 DNS 或 /etc/services 会让输出变慢且难比对。默认只显示当前用户可见的进程,查系统进程或其他用户的进程要加 sudo;部分受保护的系统进程即使 sudo 也可能信息不全,这是正常边界。
macOS 自带的是 Apple 维护的 lsof 4.91,版本比上游旧,个别新选项不存在。输出里的 COMMAND 默认截断到 9 个字符,可用 +c 0 显示完整命令名。lsof +D 会递归扫描目录,在大目录或网络卷上非常慢,能定位到具体文件时优先 lsof /path/to/file。
# 查看所有 TCP 监听端口及对应进程
% lsof -nP -iTCP -sTCP:LISTEN
# 查谁占用了 8080 端口
% lsof -nP -i :8080
# 查看某进程打开的所有文件
% lsof -p 462
# 查看某进程完整命令名,避免 9 字符截断
% lsof +c 0 -p 462 | head
# 只输出占用 3000 端口的 PID,确认后再 kill
% lsof -t -i :3000
# 查某个文件被谁打开
% lsof /etc/hosts
# 查看 UDP 套接字
% lsof -nP -iUDP
# 需要看其他用户或系统进程时加 sudo
% sudo lsof -nP -iTCP -sTCP:LISTEN
-nP 时,lsof 会反解每个地址和端口,DNS 异常时命令像卡死;排障固定用 lsof -nP。lsof -i 只显示网络文件,不会显示普通文件;反过来 lsof /path 也不显示端口,别把两类查询混在一起。kill $(lsof -t -i:3000) 可能在无输出时误杀或报错,且一次命中多个 PID;先看 lsof -nP -i :3000,再对具体 PID 发 kill -TERM。lsof +D 在大目录、APFS 快照或 SMB 挂载上会扫描很久;优先用 lsof /具体文件,或先 find 缩小范围。can't stat() 警告;先卸载失效挂载,或用 -b 避免阻塞型内核调用。can't identify protocol 通常是对端已关闭或内核协议信息不完整,不代表 lsof 坏了。合上页面,先回答,再展开对照。
lsof -nP -iTCP -sTCP:LISTEN 中 -n 和 -P 各避免什么?lsof +D 不建议随意使用?-n 禁止 IP 地址反解,-P 禁止端口号转服务名;两者都能避免 DNS/服务查询造成的延迟和输出歧义。lsof -nP -i :8080 看进程名和 PID,确认无误后再 kill -TERM <PID>;不要盲目批量 kill。lsof /path/file。
小程序版
微信扫码,随时查命令