Bash TCP programming hack!?

I had never heard of this until I ran into working on a recent project. In “bash” you can open sockets:

exec file-descriptor<>/dev/tcp/IP-or-hostname-here/port

so for example:

exec 3<>/dev/tcp/

would open port 23 (telnet) to IP “” for read and write (the “<>”) on file descriptor “3” (remember descriptors 0, 1, and 2 are used by default for stdin, stdout, and stderr respectively, so you probably don’t want to step on them). Or if you prefer easier to read:

exec 3<>/dev/tcp/

and thus it’ll also do host and service lookups.

You can then write to the socket:

echo “mylogin” >&3

or read from the socket:

cat <&3

If you don’t use “<>” but rather just “<” or “>” you can open the socket only for read or write respectively.

You can also close the socket (as all good programmers should):

exec 3<&- # Close for read
exec 3>&- # Close for write

Bash – it shakes, it bakes, it does socket programming.

To note this is an entire bash-ism, you can’t simply do:

echo “hello” >/dev/tcp/

“bash” is intercepting the “/dev/tcp” stuff and fudging it.

And I thought Perl was the only one with ugly hacks.


  1. jim Avatar

    I wish I could figure out how to use your script to retrieve this xml file….

  2. Matt Fahrner Avatar

    Without knowing exactly what you want to do with it it’s hard to say for sure, but my guess is it could be done, though using “bash” is probably far more difficult than a lot of options. If it were me I’d look to using “curl”:

    Or even just write something in Perl, which has modules to do things like HTTP “get”s.

  3. berndt Avatar

    dir matt,

    thankyou so much for this wunderfull webseit. i understand now how socket works.

Leave a Reply

Your email address will not be published. Required fields are marked *