More on Using Bash's Built-in /dev/tcp File (TCP/IP)

If you saw yesterday's Tech Tip and were looking for more on using TCP/IP with bash's built-in /dev/tcp device file then read on. Here, we'll both read from, and write to a socket.

Before I go any further, let me state that this is based on something I discovered here on Dave Smith's Blog. All I've done here is added a few improvements based on the comments to the original post. I've also added a bit of additional explanation.

The following script fetches the front page from Google:

exec 3<>/dev/tcp/www.google.com/80
echo -e "GET / HTTP/1.1\r\nhost: http://www.google.com\r\nConnection: close\r\n\r\n" >&3
cat <&3

Pretty simple, just 3 lines. The first line may be a bit confusing if you haven't seen this type of thing before. This line causes file descriptor 3 to be opened for reading and writing on the specified TCP/IP socket. This is a special form of the exec statement. From the bash man page:

exec [-cl] [-a name] [command [arguments]]

... If command is not specified, any redirections take effect in the current shell, and the return status is 0.

So using exec without a command is a way to open files in the current shell.

After the socket is open we send our HTTP request out the socket with the echo ... >&3 command. The request consists of:

GET / HTTP/1.1
host: http://www.google.com
Connection: close

Each line is followed by a carriage-return and newline, and all the headers are followed by a blank line to signal the end of the request (this is all standard HTTP stuff).

Next we read the response out of the socket using cat <&3, which reads the response and prints it out. The response being the main HTML page from Google:

$ bash tcp.sh
HTTP/1.1 200 OK
Date: Wed, 30 Sep 2009 17:28:36 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Set-Cookie: PREF=ID=...
Set-Cookie: NID=27=...
Server: gws
X-XSS-Protection: 0
Transfer-Encoding: chunked
Connection: close

fef
<!doctype html><html><head><meta ...

And that's it, with just a few more lines of code you could have your own bash based browser... well maybe not.

Mitch Frazier is an embedded systems programmer at Emerson Electric Co. Mitch has been a contributor to and a friend of Linux Journal since the early 2000s.

Load Disqus comments