Post

HN
Hacker News

TIL: You can make HTTP requests without curl using Bash /dev/TCP

I needed to check that one container could reach another over an internal Docker network: a plain GET /health against a service on a shared network. The obvious move is curl http://service:8642/health . But this app image was stripped right down, with no curl or wget and nothing else around that I could use to open a socket.

As it turns out, bash can speak HTTP by itself bash can open a TCP socket, and you can write a small HTTP request to it by hand. Opening a connection to a host and port and writing the request needs nothing beyond the shell thatโ€™s already there:

service here is just the hostname of whatever youโ€™re talking to. It has to resolve and be reachable from wherever you run this, so it needs to be set up first: a container or service name on a Docker network youโ€™ve configured, or any DNS name that resolves. Swap in your own host and port.

That prints the whole response: the status line, the headers, the blank line, and the body. To add a header, such as an Authorization: Bearer token, put another \r\n -terminated line before the blank line that ends the request:

What caught me out the first time is that /dev/tcp isnโ€™t a real device file. Thereโ€™s no such path on disk; ls /dev/tcp finds nothing, and cat /dev/tcp/... from another shell just errors. Itโ€™s a redirection that bash handles internally. From the Bash manual :

/dev/tcp/host/port โ€“ If host is a valid hostname or Internet address, and port is an integer port number or service name, bash attempts to open the corresponding TCP socket.