You SSH into a minimal container image to debug something, and curl isn’t there. Neither is wget. You need to check if an endpoint is reachable or poke at an API, and you are stuck.
Bash can actually do TCP directly. It’s been able to since Bash 2.0-something.
The trick
exec 3<>/dev/tcp/example.com/80
echo -e "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n" >&3
cat <&3
/dev/tcp/ is a bash-specific pseudo-device. Opening it sets up a TCP connection to the host and port you specify. The first line opens file descriptor 3 for read-write on that socket. You write your HTTP request to it, then read the response back.
For HTTPS you will need openssl s_client or similar, but for internal HTTP endpoints this gets you surprisingly far.
A reusable function
If you do this often enough, wrap it:
http_get() {
local host="$1"
local path="${2:-/}"
exec 3<>/dev/tcp/${host}/80
printf "GET %s HTTP/1.0\\r\\nHost: %s\\r\\n\\r\\n" "$path" "$host" >&3
cat <&3
exec 3<&-
}
http_get example.com /
When this matters
Minimal images for security scanning, single-purpose sidecars, or base images you are building from scratch — these often strip out anything not explicitly needed. If you are debugging a network issue inside one of those containers, you do not have to install curl just to test connectivity. Bash is usually there.
This is not a replacement for proper HTTP clients. But for the moment you need to check if something is listening, it saves a round-trip to install a tool.
Top comments (0)