Skip to content
shellmap

Test if a network port is open

Check whether a remote (or local) TCP port is accepting connections — for service health checks, firewall debugging, or pre-flight validation in scripts.

How to test if a network port is open in each shell

Bashunix
nc -zv example.com 443

`nc -z` is "zero-I/O" mode (just check connect, don't send data). `-v` is verbose ("succeeded" / "refused"). Some `nc` variants (BSD/OpenBSD) need different flags than GNU/`ncat`; `-w 3` adds a 3-second timeout so a black-holed host doesn't hang the script. Pure-bash zero-dependency form: `(echo > /dev/tcp/example.com/443) 2>/dev/null && echo open || echo closed` — uses bash's built-in `/dev/tcp/` virtual device (NOT a real `/dev` file; only works in bash, not POSIX sh).

Zshunix
nc -zv example.com 443

Same external `nc`. Zsh-specific: zsh has its own `ztcp` builtin (`zmodload zsh/net/tcp; ztcp example.com 443 && ztcp -c $REPLY`) but that's an obscure tool for most uses. For "wait until a port becomes open in a loop", `until nc -zv localhost 5432 2>/dev/null; do sleep 1; done` is the canonical CI / docker-wait idiom.

Fishunix
nc -zv example.com 443

Same external. Fish syntax for the wait-loop idiom: `while not nc -zv localhost 5432 2>/dev/null; sleep 1; end`. Fish doesn't have bash's `/dev/tcp/` magic — use real `nc`. For a quick reachability check from a script, also consider `curl --connect-timeout 3 -s example.com:443 >/dev/null && echo open` (curl handles both TCP and TLS, useful for HTTPS specifically).

PowerShellwindows
Test-NetConnection example.com -Port 443

The pwsh-native answer. Returns a rich object: `TcpTestSucceeded` is `$True`/`$False`; `PingSucceeded`, `RemoteAddress`, `InterfaceAlias` round out the diagnostic info. For a one-line boolean: `(Test-NetConnection example.com -Port 443 -InformationLevel Quiet)` returns just `$True`/`$False`. SLOW (~3s) because it also does DNS + ICMP ping by default. Faster: `(New-Object System.Net.Sockets.TcpClient).ConnectAsync("example.com", 443).Wait(2000)` — direct .NET socket, ~ms latency. On Linux/macOS pwsh, `Test-NetConnection` does NOT exist (Windows-only cmdlet); fall back to `nc` or the TcpClient.

cmd.exewindows
powershell -NoProfile -Command "Test-NetConnection example.com -Port 443 -InformationLevel Quiet"

cmd has no native port-test. The legacy `telnet example.com 443` is one option (BUT Telnet Client is NOT installed by default on Windows since Windows 7 — needs Optional Feature install). Shell out to pwsh (above) for the modern answer. The very-very-old-school cmd form: `netstat -an | findstr ":443"` shows local listeners but doesn't test REMOTE ports.

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • A successful TCP connect tells you the port is OPEN at the socket level — it does NOT guarantee the service behind it is healthy. A web server might accept the connect then immediately return HTTP 503; a database might accept the connect then drop you due to auth failure. For end-to-end health checks, layer an application-level probe: `curl -fs https://example.com/health || exit 1` rather than just `nc -z`.
  • CONNECT vs LISTEN: "is port X open" can mean two different things. "Is something listening on MY port X" → `ss -tln sport = :X` (Linux) / `lsof -iTCP:X -sTCP:LISTEN` (Unix) / `Get-NetTCPConnection -LocalPort X -State Listen` (pwsh) / `netstat -ano | findstr :X` (cmd). "Can I REACH port X on a remote host" → the nc / Test-NetConnection / TcpClient family from this page.
  • Firewall vs. closed-port behaviour differs. A REJECTED (RST) port closes the connection immediately — typical of "service isn't listening". A DROPPED (no response) port hangs until timeout — typical of a firewall silently dropping packets. The error messages from `nc` / `Test-NetConnection` distinguish these: "Connection refused" = service down; "Operation timed out" = firewall (or unreachable network).
  • For UDP ports, the techniques above DO NOT WORK (UDP is connectionless — there's no handshake to test). UDP "port scan" tools (`nmap -sU -p X host`) send probe packets and wait for ICMP "port unreachable" responses (which are rate-limited on most kernels). The honest answer for UDP: "you can't reliably test from outside the application protocol".

Related commands

Related tasks