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

Published 2026-06-17 · Updated 2026-06-17

---

Ever felt the frustration of needing to quickly test an API endpoint, diagnose a network issue, or just poke around a server without the overhead of installing and configuring `curl`? You've probably reached for the familiar command-line tool, but what if I told you there's a surprisingly effective, built-in alternative lurking in your operating system's kernel? It’s a technique that’s baffled many, and one that can dramatically speed up your troubleshooting and development workflows: making HTTP requests directly using `/dev/tcp` in Bash. It’s a little weird, a little obscure, and incredibly powerful when you understand how it works. Let's break it down.

The Magic of /dev/tcp

The `/dev/tcp` device is a special file in Unix-like systems (Linux, macOS, etc.) that provides a direct connection to a network socket. Think of it as a low-level interface to network communication. Instead of building a complex program to make HTTP requests, Bash can directly use this device to establish an TCP connection and send/receive data. This bypasses the need for a full-fledged HTTP client, offering a remarkably simple way to interact with services. It’s a fundamental part of the operating system’s network stack, and surprisingly, it’s readily accessible from your shell.

The key is understanding that `/dev/tcp/host/port` creates a connection to the specified host and port. The device itself behaves like a TCP socket – you can establish connections, send data, and receive data just as you would with `netcat` or `socat`. What’s remarkable is that Bash handles the low-level TCP communication for you, abstracting away much of the complexity.

Crafting the Request

Making an HTTP request with `/dev/tcp` isn't about using `curl` commands. You're building the HTTP request *directly* in your Bash script. This means you need to construct the HTTP headers and the body of the request yourself. It’s not a shortcut for complex requests, but it’s perfectly adequate for simple GET and POST requests.

Let’s look at a basic example:

```bash

request=$(echo -e 'GET / HTTP/1.0\r\nHost: example.com\r\nConnection: close\r\n' > /dev/tcp/example.com/80)

echo "$request"

echo "$request" | nc example.com 80

```

This script does the following:

1. It builds the HTTP GET request string, including the headers (Host and Connection). The `\r\n` characters are crucial for separating the headers and the request body.

2. It redirects the HTTP request string to `/dev/tcp/example.com/80`, establishing a TCP connection to the specified host and port.

3. It then prints the sent request and sends the request directly to the server via `nc`.

Handling Responses

Receiving the response is equally straightforward. `/dev/tcp` automatically handles the data transfer once the request is sent. You simply read from the device until the connection is closed.

```bash

response=$(echo -e 'GET / HTTP/1.0\r\nHost: example.com\r\nConnection: close\r\n' > /dev/tcp/example.com/80 2>&1)

echo "$response"

```

The `2>&1` redirects standard error to standard output, ensuring that any error messages from the server are also captured in the `response` variable. The script then prints the received response.

Practical Use Cases and Considerations

While `/dev/tcp` is great for quick tests and simple requests, it’s not a replacement for robust HTTP clients. However, it shines in specific scenarios. One particularly useful case is monitoring the status of a service. You could repeatedly send a GET request to a specific endpoint and check the response code to determine if the service is running.

Another useful scenario is debugging. If you're having trouble with a service, you can use `/dev/tcp` to send a simple request and examine the raw response to identify potential issues. For instance, if you’re seeing 500 errors, you can immediately see the server’s error message.

**Important Note:** `/dev/tcp` doesn't handle HTTP version negotiation or other advanced HTTP features. It’s strictly for making basic HTTP requests. Also, the `Connection: close` header is often necessary to ensure that the connection is closed after the request is sent. Without it, you might experience issues with subsequent requests.

A Powerful Shortcut

`/dev/tcp` offers a direct, low-level approach to HTTP requests that can be surprisingly efficient for simple tasks. It's a valuable tool for developers and system administrators needing a quick and immediate way to test network connectivity, diagnose problems, or automate simple HTTP interactions. It’s a reminder that sometimes, the most powerful tools are the ones hidden in plain sight.

**Takeaway:** Don't underestimate the power of `/dev/tcp` for basic HTTP requests. It provides a fast and direct way to interact with network services, offering a unique perspective on network communication.

---


Frequently Asked Questions

What is the most important thing to know about TIL: You can make HTTP requests without curl using Bash /dev/TCP?

The core takeaway about TIL: You can make HTTP requests without curl using Bash /dev/TCP is to focus on practical, time-tested approaches over hype-driven advice.

Where can I learn more about TIL: You can make HTTP requests without curl using Bash /dev/TCP?

Authoritative coverage of TIL: You can make HTTP requests without curl using Bash /dev/TCP can be found through primary sources and reputable publications. Verify claims before acting.

How does TIL: You can make HTTP requests without curl using Bash /dev/TCP apply right now?

Use TIL: You can make HTTP requests without curl using Bash /dev/TCP as a lens to evaluate decisions in your situation today, then revisit periodically as the topic evolves.