Porque esa es una característica del shell (de ksh, copiado por bash), y solo el shell.
/dev/tcp/...
no son archivos reales, el shell intercepta los intentos de redirigir a un /dev/tcp/...
archivo y luego hace un socket(...);connect(...)
(hace una conexión TCP) en lugar de un open("/dev/tcp/..."...)
(abriendo ese archivo) en ese caso.
Tenga en cuenta que tiene que escribirse así. cat < /dev/./tcp/...
o ///dev/tcp/...
no funcionará, e intentará abrir esos archivos en su lugar (que en la mayoría de los sistemas no existen y obtendrá un error).
La dirección de la redirección tampoco importa. Ya sea que utilice 3< /dev/tcp/...
o 3> /dev/tcp/...
o 3<> /dev/tcp/...
o incluso 3>> /dev/tcp/...
no hará ninguna diferencia, podrás tanto de leer y escribir desde / hasta que el descriptor de fichero para recibir datos / enviar a través de ese socket TCP.
Cuando lo hace cat /dev/tcp/...
, eso no funciona porque cat
no implementa ese mismo manejo especial, hace un me open("/dev/tcp/...")
gusta para cada archivo (excepto -
), solo lo hace el shell (ksh, bash solamente), y solo para el destino de las redirecciones.
Ese cat -
es otro ejemplo de una ruta de archivo manejada especialmente. En lugar de hacer un open("-")
, lee directamente desde el descriptor de archivo 0 (stdin). cat
y muchas utilidades de texto hacen eso, el shell no lo hace por sus redireccionamientos. Para leer el contenido del -
archivo, necesita cat ./-
, o cat < -
(o cat - < -
). Sin embargo /dev/stdin
, en sistemas que no tienen , bash
hará algo similar para las redirecciones desde ese archivo (virtual). GNU awk
hace lo mismo para /dev/stdin
, /dev/stdout
, /dev/stderr
incluso en sistemas que sí tienen este tipo de archivos que pueden causar algunas sorpresas en sistemas como Linux, donde los archivos se comportan de manera diferente.
zsh
también tiene soporte de socket TCP (y flujo de dominio Unix), pero eso se hace con un ztcp
(y zsocket
) incorporado, por lo que es menos limitado que el enfoque ksh / bash. En particular, también puede actuar como un servidor que ksh / bash no puede hacer. Sin embargo, todavía es mucho más limitado que lo que puedes hacer en un lenguaje de programación real.