Why are < or > required to use /dev/tcp

Because that's a feature of the shell (of ksh, copied by bash), and the shell only.

/dev/tcp/... are not real files, the shell intercepts the attempts to redirect to a /dev/tcp/... file and then does a socket(...);connect(...) (makes a TCP connection) instead of a open("/dev/tcp/..."...) (opening that file) in that case.

Note that it has to be spelled like that. cat < /dev/./tcp/... or ///dev/tcp/... won't work, and will attempt to open those files instead (which on most systems don't exist and you'll get an error).

The direction of the redirection also doesn't matter. Whether you use 3< /dev/tcp/... or 3> /dev/tcp/... or 3<> /dev/tcp/... or even 3>> /dev/tcp/... won't make any difference, you'll be able to both read and write from/to that file descriptor to receive/send data over that TCP socket.

When you do cat /dev/tcp/..., that doesn't work because cat doesn't implement that same special handling, it does a open("/dev/tcp/...") like for every file (except -), only the shell (ksh, bash only) does, and only for the target of redirections.

That cat - is another example of a file path handled specially. Instead of doing a open("-"), it reads directly from the file descriptor 0 (stdin). cat and many text utilities do that, the shell doesn't for its redirections. To read the content of the - file, you need cat ./-, or cat < - (or cat - < -). On systems that don't a have /dev/stdin, bash will however do something similar for redirections from that (virtual) file. GNU awk does the same for /dev/stdin, /dev/stdout, /dev/stderr even on systems that do have such files which can cause some surprises on systems like Linux where those files behave differently.

zsh also has TCP (and Unix domain stream) socket support, but that's done with a ztcp (and zsocket) builtins, so it's less limited than the ksh/bash approach. In particular, it can also act as a server which ksh/bash can't do. It's still much more limited than what you can do in a real programming language though.


You seem to be confusing the ideas or reading a file and executing a command. The difference between data and instruction.

Googles front page is not an executable program. And if it was, it would not be safe to run it.

The redirection characters (including < and >), are used to direct data into a command.

We could do cat < /dev/tcp/towel.blinkenlights.nl/23 However this won't work for /dev/tcp/www.google.com/80 as this port will not respond until we send GET / HTTP/1.0\r\n\r\n

So try

{
  printf >&3 'GET / HTTP/1.0\r\n\r\n'
  cat <&3
} 3<>/dev/tcp/www.google.com/80