必须用 $nf 是因为 ss 命令不同版本字段顺序不固定,而 tcp 状态总在输出末尾,$nf 可靠获取最后一列状态值;state all 不可省略,否则会漏掉 syn-recv、close-wait 等关键状态,导致统计不全。

直接用 ss -tn state all | awk '{print $NF}' | sort | uniq -c | sort -nr 就能准确统计所有 TCP 连接状态的并发数量,比如 ESTABLISHED、TIME-WAIT、LISTEN、SYN-RECV 等。这个命令稳定、高效,不依赖 netstat,也适配不同版本的 ss 输出格式。
为什么必须用 $NF 而不是固定列号
ss 命令不同版本字段顺序可能变化,比如有的版本状态在第 6 列,有的在第 7 列。$NF 表示“最后一列”,而 TCP 状态总在输出末尾,所以更可靠。执行前可先跑 ss -tn | head -3 看一眼实际格式,验证状态是否确实在最后一列。
state all 是关键,不能省略
不加 state all,ss 默认可能只显示部分状态(如漏掉 SYN-RECV、FIN-WAIT-2),导致统计不全。加上后才能覆盖全部连接状态,确保结果完整。尤其排查异常连接堆积时,漏掉 SYN-RECV 或 CLOSE-WAIT 容易误判问题根源。
按端口或方向做细分统计
如果只想看某服务(如 Web)的状态分布,可以叠加过滤:
- 查监听在 80 端口上的所有状态:ss -tn sport :80 | awk '{print $NF}' | sort | uniq -c | sort -nr
- 查主动连出去的 443 连接状态:ss -tn dport :443 | awk '{print $NF}' | sort | uniq -c | sort -nr
- 只统计已建立且连 80 端口的:ss -tn state established sport :80 | wc -l
别用 grep 匹配状态名
grep ESTABLISHED 容易误匹配到日志路径、进程名或字段内含子串(如 established_time)。ss 原生支持 state established 语法,大小写不敏感,语义明确,无歧义。同样,统计 TIME-WAIT 时用 ss -tn state time-wait | wc -l 比 grep 更干净。











