登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

ss 怎样把连接关联到进程

来源:17golang原创

时间:2026-10-15 05:46:19 327浏览 收藏

排查“8080 端口被占用”时,真正有用的不是再看一遍端口号,而是把 socket 和持有它的进程放到同一条结果里。ss 的 -p(--processes)就是进程关联开关;监听范围、数字地址和过滤条件则由其他选项分别负责。

官方地址:https://github.com/iproute2/iproute2

这篇只讨论 -p 与权限边界。示例中的程序名、PID 和文件描述符是说明格式,不代表某台机器上的真实运行结果。

ss 的监听范围、进程关联和数字地址选项静态关系图
图1:ss 选项职责与 socket 信息边界的结构示意图;这是原创说明图,不是终端截图或运行证据。

先把三个选项的职责分开

ss -lntp 常被当成“查看端口对应进程”的固定口诀,但它其实包含了三个独立决策:-l 只保留监听 socket,-n 不把端口反查成服务名,-p 才负责尝试显示使用该 socket 的进程。

# -l 只看监听,-n 保留数字地址,-t 限定 TCP,-p 显示关联进程
sudo ss -lntp

如果只想看 UDP,把 -t 换成 -u;要同时看 TCP 和 UDP,可以使用 -lntup。这里的关键是不要把 -p 理解成“按 PID 搜索”:它是在已有 socket 列表上补充进程信息。

选项负责什么不负责什么
-l把结果范围收窄到监听 socket不提供进程名或 PID
-p显示使用 socket 的进程不替代端口过滤
-n保留数字地址和端口不改变进程关联
-t/-u选择 TCP 或 UDP不决定权限范围

用过滤条件锁定端口

机器上监听服务很多时,先缩小 socket 集合,再看进程关联,比把整张列表交给人眼筛选更容易解释。sport 表示本地端口,可以与 -lntp 组合。

# 只查看本机 TCP 8080 的监听 socket,并尝试补出进程信息
sudo ss -lntp 'sport = :8080'

如果需要检查连接而不是监听者,去掉 -l,再根据场景使用 state established 等过滤条件。端口过滤和进程关联是两层逻辑:前者决定看哪些 socket,后者决定每个 socket 后面能否显示持有者。

# 先按本地端口筛选,再保留数字地址和进程关联信息
sudo ss -ntp 'sport = :8080'

读懂 users 输出里的四个字段

开启 -p 后,常见结果会在末尾出现类似 users:(("my-worker",pid=2468,fd=7)) 的信息。它不是一列简单的“服务名”,而是一个进程引用集合。

  • my-worker:进程名,帮助人快速识别程序。
  • pid=2468:进程 ID,可继续交给 ps 查看启动参数和用户。
  • fd=7:该进程打开这个 socket 的文件描述符。
  • 多个条目:可能表示多个进程或线程/进程引用同一个 socket,不能只取第一个名字就下结论。
# 用 PID 复核命令行和运行用户;不要把程序名当成唯一证据
ps -o user=,pid=,ppid=,args= -p 2468

这个复核动作解决了一个常见误判:ss 告诉你 socket 关联到了哪个 PID,ps 再告诉你该 PID 的父进程、启动参数和账号。两者结合,才能判断是主服务、子进程还是被继承的文件描述符。

ss 权限、socket inode、进程 PID 与 users 输出的静态关系图
图2:权限与进程关联结果的结构示意图;这是原创说明图,不是执行截图。

为什么同一条命令在不同用户下结果不同

-p 不是绕过权限的开关。ss 需要把 socket 与进程的内核对象、进程目录和文件描述符关联起来;当前用户没有足够权限时,某些条目可能仍能显示地址和状态,却看不到完整的 users 信息。

# 在有权限的维护窗口中查看监听进程;sudo 只扩大本次命令的身份权限
sudo ss -lntp 'sport = :8080'

如果普通用户查不到进程,先不要急着判断“端口没有进程”。可以按下面的顺序解释结果:

  1. 确认你查看的是同一台主机,并且端口协议没有写错;TCP 和 UDP 是不同的 socket 集合。
  2. 用具备必要权限的账号重试 -p,比较是否只是进程关联字段变化。
  3. 确认目标进程是否在另一个网络命名空间;宿主机看到的 socket 列表不一定等于容器或服务内部的视图。
  4. 拿到 PID 后再用 ps 核对账号、父进程和启动参数,不要只依据显示名称。

权限提升也要有边界:生产环境优先把命令输出限制到单一协议和端口,避免把不必要的进程信息写入共享日志;需要长期自动化时,再评估专用运维账号或最小权限策略。

形成可复用的排障模板

把这类排查拆成“范围、关联、复核”三段后,命令不容易越写越长。下面模板保留最常用的变量,适合临时处理端口占用问题。

# 只替换协议和端口,保留数字地址与进程关联,减少误判
PROTO="tcp"
PORT="8080"

# 根据协议选择 socket 集合;参数值来自本次排障目标,不从不可信输入直接拼接
if [ "$PROTO" = "udp" ]; then
  SOCKET_KIND="u"
else
  SOCKET_KIND="t"
fi

# -l 限定监听,sport 限定本地端口,-p 尝试补齐进程信息
sudo ss -ln"$SOCKET_KIND"p "sport = :$PORT"

如果输出中有 pid,再把它交给 ps 做一次身份和父子关系复核;如果只有 socket 状态没有进程信息,优先从权限、协议、网络命名空间三个方向解释,而不是重复执行完全相同的命令。

几个容易混淆的问题

只加 -p 就能找到监听端口吗?

不一定。-p 只要求显示进程关联;要限定监听 socket,仍然需要 -l,要限定协议则加 -t 或 -u。

为什么显示了端口,却没有 users?

常见原因是当前用户权限不足、查看了不同的网络命名空间,或者该 socket 没有可供 ss 映射到的进程信息。先用有权限的账号和正确的命名空间复核。

看到多个 PID 时该杀哪个?

不要凭第一行决定。先用 ps -o user=,pid=,ppid=,args= 查看父进程和启动参数,确认哪个进程是服务所有者,再按发布和运维流程处理。

总结

ss 把连接关联到进程的关键是分工:-l 定义监听范围,-t/-u 定义协议,过滤器定义端口集合,-p 才负责补充进程名、PID 和文件描述符。看不到 users 时,优先检查权限与网络命名空间;看到 PID 后,再用 ps 复核账号和父进程。这样得到的结论比单独记住一条“万能命令”更可靠。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>