Back
Making HTTP requests without curl, using bash /dev/tcp
SiTech AI Team2 წთ. საკითხავი

Making HTTP requests without curl, using bash /dev/tcp

A developer who needed to check that one container could reach another on an internal Docker network found no curl and no wget in the image, and wrote a raw HTTP request with nothing but bash and its /dev/tcp redirection.

A developer who needed to check that one container could reach another over an internal Docker network found the usual tool missing: the application image had been stripped down and contained neither curl nor wget, nor anything else that could open a socket. The solution, documented in a short write-up, relies on a feature built into bash itself — the /dev/tcp pseudo-device — to open a TCP socket and speak HTTP by hand.

An HTTP request written by hand

The approach needs nothing beyond the shell that is already present. A file descriptor is opened against the target host and port with exec 3<>/dev/tcp/service/8642, after which a printf command writes a minimal request — the request line, a Host header and Connection: close — into that descriptor, and cat <&3 prints whatever comes back: the status line, the headers and the body. Adding an Authorization: Bearer header means inserting one more CRLF-terminated line before the blank line that closes the request.

Not a device file, but a bash redirection

The detail that surprises most people is that /dev/tcp does not exist on disk. It is a redirection that bash handles internally: bash performs the DNS lookup and the connect(2) call, then hands the socket a file descriptor. The names were chosen because no real Unix has a /dev/tcp hierarchy, so there is nothing for them to collide with. Because this is a bash feature and not POSIX, it does not work in dash or zsh, and a script has to invoke bash directly.

What it cannot do

The author is explicit that this is not an HTTP client. It does not parse responses, follow redirects, handle chunked encoding or compression, retry, or negotiate TLS — the socket is plaintext only, so https would require openssl s_client. Omitting the Connection: close header means the server keeps the connection open and cat waits forever for bytes that never arrive; wrapping the command in timeout 6 bash -c '...' guards against that. The feature is also a compile-time option, enabled with --enable-net-redirections, which most mainstream builds turn on but Debian shipped disabled for years. For everyday work the conclusion is unchanged: curl remains the right tool. Inside a deliberately minimal container where nothing can be installed, the trick answers a quick connectivity question without adding a package.

SSiTech

SiTech — AI-powered web development

We build fast, modern websites and bring AI into real business workflows. Have a project or a question? We'd love to help.