In this lesson, you will learn how to communicate with network services directly from your shell by treating sockets as file descriptors.
The Shell as a Network Client
In Linux, the "everything is a file" philosophy extends to networking. When you open a network socket, the kernel assigns it a file descriptor (FD), just like a regular text file. Because we have already mastered File Descriptor Management, we can use Bash’s built-in /dev/tcp/ and /dev/udp/ virtual paths to open connections without needing external tools like curl or netcat.
To open a connection, we use the exec command to assign a specific FD to a remote host and port. For example, to connect to a web server on port 80:
# Open a file descriptor (3) for read/write access to example.com
exec 3<>/dev/tcp/example.com/80
# Send an HTTP GET request through the descriptor
echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" >&3
# Read the response from the descriptor
head -n 5 <&3
# Close the descriptor
exec 3>&-
Why This Matters
By using /dev/tcp/, you bypass the need for external network utilities, which is incredibly useful in restricted environments (like minimal container images or locked-down recovery shells).
When you write to the FD using >&3, the Bash shell translates your string into packets sent over the network. When you read from <&3, the shell waits for the remote server to send data back, populating your input stream. Because this uses standard file descriptors, you can pipe these outputs into your favorite tools like sed or awk to perform Streaming Data Transformation on incoming network traffic in real-time.
Important Constraints
Remember that these virtual device paths are a unique feature of the Bash shell. They are not actual files on the disk, so you cannot list them with ls. Furthermore, these operations are synchronous; if the server does not respond, your script will hang unless you handle the timeout or use Non-blocking I/O Patterns to manage the connection state.
Key Takeaway: By utilizing the /dev/tcp/ virtual file path, you can perform raw network socket communication by treating remote network services as simple, readable, and writable file descriptors.