Skip to content
shellmap

routeInspect and modify the kernel IP routing table across all 5 shells

Equivalents in every shell

Bashunix
route -n

`route` is from `net-tools` (deprecated on Linux but still installed). `-n` shows numeric output (no DNS lookups on gateway IPs — much faster). Modern Linux equivalent: `ip route` or `ip route show`. Add a static route: `sudo route add -net 10.0.0.0/24 gw 192.168.1.1` (or `sudo ip route add 10.0.0.0/24 via 192.168.1.1`). Like `ifconfig`, changes are NOT persisted across reboot.

Zshunix
route -n

On macOS `route -n` is the SAME spelling but different subcommand syntax. To see the routing table: `netstat -nr` (macOS) or `route -n get default` (single-route lookup). To add: `sudo route -n add -net 10.0.0.0/24 192.168.1.1`. macOS `route` is BSD-derived; Linux `route` is from `net-tools` — flags differ enough that scripts cannot share lines.

Fishunix
route -n

Same external. The most useful one-liner for "where does outbound traffic to X go right now": `ip route get 8.8.8.8` (Linux) or `route -n get 8.8.8.8` (macOS). This is what you want when debugging "why is my packet going through the VPN" or "why does only one app see the internet".

PowerShellwindows
Get-NetRoute

Lists every route in every routing table. Filter: `Get-NetRoute -DestinationPrefix 0.0.0.0/0` (default routes), `Get-NetRoute -InterfaceAlias "Wi-Fi"`. Add: `New-NetRoute -DestinationPrefix 10.0.0.0/24 -InterfaceAlias "Ethernet" -NextHop 192.168.1.1 -RouteMetric 10`. Remove: `Remove-NetRoute -DestinationPrefix 10.0.0.0/24 -Confirm:$false`. Routes added this way persist across reboots (registry-backed).

cmd.exewindows
route print

`route print` shows the routing table (IPv4 first half, IPv6 second). `route add 10.0.0.0 mask 255.255.255.0 192.168.1.1` adds a non-persistent route; add `-p` to persist (`route -p add ...`). `route delete 10.0.0.0` removes. `route change 0.0.0.0 mask 0.0.0.0 192.168.1.254` swaps the default gateway. Note the Windows-specific syntax `mask` instead of CIDR.

Worked examples

Show the current routing table

Bash
route -n
Zsh
netstat -nr
PowerShell
Get-NetRoute | Format-Table DestinationPrefix, NextHop, InterfaceAlias, RouteMetric
cmd.exe
route print

Add a persistent static route (survives reboot)

Bash
sudo ip route add 10.0.0.0/24 via 192.168.1.1
PowerShell
New-NetRoute -DestinationPrefix 10.0.0.0/24 -InterfaceAlias Ethernet -NextHop 192.168.1.1
cmd.exe
route -p add 10.0.0.0 mask 255.255.255.0 192.168.1.1

Find which interface and gateway will be used to reach a destination

Bash
ip route get 8.8.8.8
Zsh
route -n get 8.8.8.8
PowerShell
Find-NetRoute -RemoteIPAddress 8.8.8.8
cmd.exe
route print 8.8.8.8

Gotchas

  • Linux `route` (net-tools) is DEPRECATED but still installed nearly everywhere. The modern `ip route` is the long-term answer. Both work on most distros; new scripts should use `ip route`. Container images sometimes ship neither — `apt install iproute2 net-tools` to get both.
  • macOS `route` does NOT show the table directly — `route` with no args prints usage. The macOS way to see the table is `netstat -nr`. This catches Linux users on Macs every time. To remember: on macOS `route` is for CHANGING the table, `netstat -nr` is for SEEING it.
  • Windows `route add` without `-p` adds a NON-persistent route that vanishes on reboot. `route -p add` persists by writing to `HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\PersistentRoutes`. The PowerShell `New-NetRoute` cmdlet persists by default — flip behavior using `-PolicyStore ActiveStore` (non-persistent) vs default `PersistentStore` (persistent).
  • On systems with multiple interfaces, the metric decides priority. Both Linux and Windows pick the lowest-metric default route. To FORCE traffic over a specific interface, either (a) raise the metric on the OTHER default routes, or (b) use policy routing (`ip rule add ...` on Linux, `route ADD ... METRIC 1` on Windows). VPN clients commonly inject high-priority default routes — sometimes you want them, sometimes not.
  • IPv6 has its own routing table that lives in PARALLEL to IPv4. `ip -6 route` (Linux), `netstat -nr -f inet6` (macOS), `route print -6` (Windows). Forgetting that an app may have a working IPv6 path while IPv4 is broken explains a lot of "why is curl slow but ping works" mysteries — `curl` happy-eyeballs IPv6 first.

WSL & PowerShell Core notes

pwsh`Get-NetRoute` / `New-NetRoute` / `Remove-NetRoute` are Windows-only. On Linux/macOS pwsh, shell out: `& ip route` (Linux) or `& netstat -nr` (macOS). For programmatic access on every pwsh, `[System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces()` returns per-interface IP+gateway info but NOT the full routing table — for that there is no clean cross-platform .NET API.
WSLInside WSL2 `ip route` shows the WSL VM's routes — the VM has its own routing table separate from Windows. The Windows-host routing table is invisible from WSL. To see it: `route.exe print` from inside WSL bash (works because Windows binaries are auto-discoverable on $PATH inside WSL). WSL2's default gateway is the Hyper-V virtual switch — outbound NATs through the Windows host.

Related commands