lsof -u 无法显示 unix 域套接字的连接详情,仅列出路径、pid 和访问模式,不区分监听/已连接状态,也不显示对端;需结合 ss -x 和 /proc/pid/fd 手动排查。

lsof -U 命令本身不能显示“连接详情”
lsof -U 只列出所有打开的 Unix 域套接字(AF_UNIX)文件,但它**不区分监听、已连接、未连接状态**,也不显示对端路径或连接关系。你看到的只是每个套接字文件的路径(如 /var/run/docker.sock)、所属进程、PID 和访问模式(u 表示读写,w 表示只写等),但没有“客户端连了谁”“服务端接受了哪个 fd”这类连接级信息。
Unix 域套接字不像 TCP 那样有明确的 client/server 连接状态映射;内核不维护类似 /proc/net/unix 中的“peer”字段(该字段在 Linux 中长期为 00000000,无实际意义)。所以所谓“连接详情”在 Unix 域套接字层面,本质上是模糊的——多数时候只有路径和进程绑定关系可查。
真正能查到“连接方”的替代方式:结合 /proc/PID/fd 和套接字路径
如果你发现某个进程打开了一个 Unix 套接字(比如 lsof -U -p 1234 显示它持有一个 /tmp/mysock),而你想知道“谁连了它”,唯一可行路径是:检查其他进程的 /proc/[pid]/fd/ 目录下是否有指向同一路径的符号链接。
-
lsof -U | grep '/tmp/mysock'找出所有涉及该路径的进程 - 对每个 PID,执行
ls -l /proc/[pid]/fd/ | grep '/tmp/mysock' - 若某 fd 指向
/tmp/mysock且类型为socket,说明该进程正通过该路径通信——但无法判断它是 client 还是 server,除非结合进程行为(如是否调用bind()或connect()) - 注意:
lsof -U输出中TYPE列为unix的条目,NAME是路径;而TYPE为LOCAL的条目,NAME是抽象命名空间地址(形如@docker),这种无法通过文件系统查找对端
更实用的排查组合:lsof -U + ss -x
ss -x(来自 iproute2)比 lsof -U 更贴近网络视角,能区分监听(LISTEN)与已建立(ESTAB)状态,尤其对抽象套接字支持更好:
-
ss -xln:列出所有监听中的 Unix 套接字(-l)及其路径(-n禁用解析,避免卡 DNS) -
ss -xnp:显示监听进程名和 PID(需要 root 权限,否则pid/name列为空) -
ss -x | grep ESTAB:尝试找已建立连接——但注意,Linux 内核对 Unix 域套接字的ESTAB状态标记很弱,很多连接不会出现在这里,尤其是短连接或使用SOCK_DGRAM的场景 -
lsof -U和ss -x结果常不一致:前者靠遍历/proc/*/fd,后者读取/proc/net/unix,二者数据源不同,覆盖范围也不同
容易被忽略的关键点:抽象命名空间套接字不可见于文件系统
以 @ 开头的套接字(如 @/tmp/dbus-XXXX)属于 Linux 抽象命名空间,它们不占用文件系统路径,lsof -U 能显示(NAME 列为 @...),但你无法用 ls /proc/*/fd/ | grep '@' 定位对端——因为抽象地址不映射到磁盘路径,只能靠 ss -x 查看,且必须加 -n 才能显示原始地址。
另外,lsof -U 默认不显示未绑定的套接字(如刚 socket() 创建但还没 bind() 的 fd),也不显示已关闭但尚未被内核回收的“zombie”套接字。真正想看清全貌,得同时看 lsof -U、ss -x、以及必要时手动翻 /proc/[pid]/fd/ ——没有一键命令能给出你想象中的“连接详情”。











