CLI AI

netstat: command not found — 改用 ss

2026-07-16

ss -tulpn 就是 netstat -tulpn 的直接替代,而且系统里已经有了。netstat 来自 net-tools 包,现代的精简系统和容器镜像是故意不装它的,再去装回来只是治标。路由部分也搬了家:netstat -r 现在写作 ip route。

1. 这条命令为什么不见了

clai
$ clai 显示正在监听的端口→ netstat -tulpnbash: line 1: netstat: command not found

net-tools 已经多年无人维护,所以精简镜像干脆不带。在容器里执行 apt-get install net-tools 常常得到 E: Unable to locate package net-tools——没什么可装的,也没什么可惜的:ss 来自 iproute2,那个是在的。

2. netstat -tulpn 的直接替代

clai
$ clai 看看谁在监听 8099 端口→ ss -tulpn 'sport = :8099'Netid State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess                              tcp   LISTEN 0      5          127.0.0.1:8099      0.0.0.0:*    users:(("python3",pid=1034062,fd=3))

参数还是你熟悉的那些:-t tcp,-u udp,-l 监听,-p 进程,-n 不解析名字。新东西是 'sport = :8099'——这是 ss 自己求值的过滤器,而不是对输出做 grep。

3. 看看究竟谁连上来了

clai
$ clai 显示 8099 端口上的连接→ ss -tan 'dport = :8099 or sport = :8099'State     Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN    0      5          127.0.0.1:8099      0.0.0.0:*    TIME-WAIT 0      0          127.0.0.1:8099    127.0.0.1:51350

netstat 根本没有过滤语言,所以一切都以管道接 grep 收场。这里 state established、state time-wait、dport 和 sport 可以用 and 和 or 组合。

4. 用摘要代替 netstat -s

clai
$ clai 显示套接字使用摘要→ ss -sTotal: 2161TCP:   190 (estab 58, closed 108, orphaned 0, timewait 29)

第一行统计整台机器的所有套接字,第二行按状态拆分 TCP。timewait 数量大是正常的;orphaned 数量大就该去看看应用了。

5. 替代 netstat -r 的是 ip,不是 ss

clai
$ clai 显示路由表→ ip routedefault via 172.17.0.1 dev eth0 172.17.0.0/16 dev eth0 scope link  src 172.17.0.2

路由、网卡和地址都搬进了 ip:netstat -r 是 ip route,netstat -i 是 ip -s link,ifconfig 是 ip addr。留给 ss 的只有套接字。

6. 完整对照表

clai
$ clai 列出我常用的每个 netstat 参数对应的 ss 写法→ ss -tulpn        # netstat -tulpn→ ss -an           # netstat -an→ ss -s            # netstat -s→ ip route         # netstat -r→ ip -s link       # netstat -i→ ip maddr         # netstat -g

六行覆盖了大多数人在 netstat 里敲过的一切。如果 ss -s 太粗,nstat 会给出按协议分的长长计数器。

Gotchas

  • 没有 root 时,别人的进程那一列是空的。 自己的套接字总会显示 users:(("name",pid=…)),其余需要 sudo。端口明明被占用但 Process 为空,几乎总是"不是你的进程",而不是"没有进程"。
  • 没有持续刷新模式。 netstat 有 -c 每秒重复输出;ss --help 里没有任何类似选项。重复交给外面做:watch -n1 'ss -tan'。
  • 过滤器里的括号必须加引号。 ss -tan 'sport = :8099' 即使不加引号也能用,因为 shell 只是原样传三个词。但 ss -tan ( sport = :8099 ) 根本到不了 ss:shell 会以 syntax error near unexpected token '(' 结束。整个表达式加引号,从此不必再想。

Related questions

万一我真的需要 netstat 呢? 在完整系统上 sudo apt install net-tools 能装回来,但精简镜像里压根没有这个包。记住上面那六行更省事。

怎么看每个进程的带宽? ss 显示连接,不显示速度。要看吞吐得用 nethogs 或 /proc/<pid>/net/dev 里的计数器。

查端口占用最短的写法是什么? ss -tulpn | grep :8099——懒得回忆过滤器语法时就用它。

See also

当你的手指还在敲 netstat 时,CliAI 会替你写出 ss 的过滤器,并在执行前把命令显示出来。一行安装。