CLI AI

netstat: command not found — use ss instead

2026-07-16

ss -tulpn is the direct replacement for netstat -tulpn, and it is already installed. netstat shipped in net-tools, a package that modern minimal systems and container images leave out on purpose — installing it is treating the symptom. Routing moved too: netstat -r is now ip route.

1. Why the command disappeared

clai
$ clai show listening ports→ netstat -tulpnbash: line 1: netstat: command not found

net-tools has been unmaintained for years, so slim images drop it. Inside a container apt-get install net-tools often answers E: Unable to locate package net-tools — there is nothing to install, and nothing to miss: ss comes from iproute2, which is already there.

2. The direct replacement for netstat -tulpn

clai
$ clai show what is listening on port 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))

The flags are the same ones you already know: -t tcp, -u udp, -l listening, -p process, -n no name resolution. What is new is 'sport = :8099' — a filter evaluated by ss itself instead of a grep over the output.

3. See who is actually connected

clai
$ clai show connections on port 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 had no filter language at all, so everything ended in a pipe to grep. Here state established, state time-wait, dport and sport combine with and and or.

4. A summary instead of netstat -s

clai
$ clai show a summary of socket usage→ ss -sTotal: 2161TCP:   190 (estab 58, closed 108, orphaned 0, timewait 29)

The first line counts every socket on the machine, the second breaks TCP down by state. A large timewait number is normal; a large orphaned number is a reason to go look at the application.

5. netstat -r is replaced by ip, not by ss

clai
$ clai show the routing table→ ip routedefault via 172.17.0.1 dev eth0 172.17.0.0/16 dev eth0 scope link  src 172.17.0.2

Routes, interfaces and addresses all moved into ip: netstat -r is ip route, netstat -i is ip -s link, and ifconfig is ip addr. Only sockets stayed with ss.

6. The whole translation table

clai
$ clai list the ss equivalent of every netstat flag I use→ 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

Six lines cover everything most people ever typed into netstat. nstat gives the long protocol counters if ss -s is too coarse.

Gotchas

  • Without root the Process column is empty for other people's processes. Your own sockets always show users:(("name",pid=…)); everything else needs sudo. An empty Process on a busy port almost always means "not your process", not "no process".
  • There is no continuous mode. netstat had -c to repeat every second; ss --help lists nothing of the kind. Do the repeating outside: watch -n1 'ss -tan'.
  • Parentheses in a filter must be quoted. ss -tan 'sport = :8099' works even unquoted, because the shell just passes three words through. But ss -tan ( sport = :8099 ) never reaches ss at all — the shell dies with syntax error near unexpected token '('. Quote the whole expression and stop thinking about it.

Related questions

What if I really need netstat? sudo apt install net-tools brings it back on a full system, but on slim images the package doesn't exist at all. Learning six lines of the table above is the shorter path.

How do I see bandwidth per process? ss shows connections, not speed. For throughput you need nethogs or the counters in /proc/<pid>/net/dev.

What's the shortest way to find who holds a port? ss -tulpn | grep :8099 — fine when you don't feel like recalling the filter syntax.

See also

CliAI writes the ss filter for you when your fingers still type netstat, and shows the command before it runs. Install it in one line.