Netcat Cheatsheet

Basics and Flags

Use this Netcat reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Which netcat do you have

"netcat" is three unrelated programs plus a rewrite, and their flags differ in ways that break copy-pasted commands. Check first.

nc -h 2>&1 | head -3
ncat --version
readlink -f "$(which nc)"     # Linux, often a symlink into alternatives
VariantBinaryShips onTell
OpenBSD ncncDebian/Ubuntu (netcat-openbsd), Alpine, *BSDUsage line lists -N, -U, -X, -Z
macOS ncncmacOS, Apple's fork of OpenBSD ncUsage line has --apple-* options
netcat-traditionalnc, nc.traditionalDebian (netcat-traditional)Prints [v1.10-…], has -e
GNU netcatnc, netcatSome distros (netcat 0.7.x)Long options, --exec, --tunnel
NcatncatNmap package, everywhereNcat 7.x ( https://nmap.org/ncat )
BusyBox ncncContainers, embeddedTiny usage, -e present, little else

Ncat is the one to prefer when you have a choice. It is maintained, portable, and adds TLS, access control, and proxying that the others lack. nc in a scratch container is usually BusyBox with almost no options.

Flag compatibility table

The flags that matter, and where they exist. A dash means absent.

PurposeOpenBSD ncmacOS nctraditionalGNU netcatNcat
Listen-l-l-l-l-l
Keep listening-k-k——-k
UDP-u-u-u-u-u
No DNS-n-n-n-n-n
Verbose-v-v-v-v-v
Connect / read timeout-w n-w n-w n-w n-w n
Zero-I/O scan-z-z-z-z-z
Source port-p-p-p-p-p
Source address-s-s-s-s-s
Randomize ports-r-r-r-r—
Delay between lines-i n-i n-i n-i n-d n
Telnet negotiation-t-t-t-T-t
CRLF line endings-C-c——-C
Execute a program——-e-e-e / -c
Shutdown write on EOF-N———--send-only
Wait n secs after EOF-q n———-q n
Unix socket-U-U——-U
SOCKS/HTTP proxy-x, -X-x, -X——--proxy
TLS————--ssl
IPv4 / IPv6 only-4 / -6-4 / -6——-4 / -6
Hex dump the session——-o file-o file-x file

The three that cause the most confusion:

- -e does not exist in OpenBSD or macOS nc. It was removed deliberately. Recipes using nc -e come from netcat-traditional or BusyBox. Use ncat -e or ncat -c. - -c means two different things. On macOS nc it sends CRLF. On Ncat it runs a command through /bin/sh. Pasting nc -c expecting Ncat behavior silently does nothing useful. - -t versus -T. GNU netcat uses -t for TCP and -T for telnet negotiation, the reverse of everyone else.

Two modes, one binary

Everything netcat does is one of two things.

# Client: connect out to host:port, wire stdin/stdout to the socket
nc example.com 80

# Server: bind a port, wait for one connection, wire stdin/stdout to it
nc -l 8080

Between those endpoints netcat is a plain pipe. It adds no framing, no protocol, no encoding. Whatever bytes you type go out, whatever comes back lands on stdout. That is the whole design, and it is why netcat works for any text protocol without knowing what it is.

Flags you will use every session

nc -v -n -w 5 10.0.0.5 443     # verbose, no DNS, 5s timeout
nc -l -k -p 8080               # listener that survives disconnects
nc -u -l 5514                  # UDP listener
nc -z -v 10.0.0.5 22           # just report open or closed
FlagWhy you want it
-vOtherwise a failed connection is completely silent
-nSkips DNS, so a hang is the network and not the resolver
-w 5Without it a filtered port hangs for the OS default, often 2 min
-kListener accepts a second connection instead of exiting
-zConnect, report, close. No data transferred
-uUDP. Changes the semantics substantially, see the UDP topic

-v is close to mandatory. Plain nc host port on a closed port exits with status 1 and prints nothing at all.

Exit status

nc -z -w 3 10.0.0.5 443 && echo open || echo "closed or filtered"
StatusMeaning
0Connected successfully, or the transfer completed
1Connection refused, timed out, or otherwise failed
2Usage or argument error (varies by variant)

-z plus the exit status is the whole reason netcat shows up in health checks and container entrypoints. But 0 only means the TCP handshake completed, and says nothing about whether the application behind the port is healthy.

The port-open one-liner without netcat

Worth knowing, because minimal images often have no nc at all.

# bash, no external binary
timeout 3 bash -c 'cat < /dev/null > /dev/tcp/10.0.0.5/443' \
  && echo open || echo closed

# Read a banner the same way
exec 3<>/dev/tcp/example.com/80
printf 'GET / HTTP/1.0\r\n\r\n' >&3
cat <&3
exec 3<&-

/dev/tcp/host/port is a bash feature, not a real device, so it is absent in sh, dash, and busybox ash. TCP only, no UDP, no listening.