Perché questa è una caratteristica della shell (di ksh, copiata da bash) e solo della shell.
/dev/tcp/...non sono file reali, la shell intercetta i tentativi di reindirizzamento a un /dev/tcp/...file e quindi effettua una socket(...);connect(...)(stabilisce una connessione TCP) anziché una open("/dev/tcp/..."...)(apertura di quel file) in quel caso.
Si noti che deve essere scritto in questo modo. cat < /dev/./tcp/...o ///dev/tcp/...non funzionerà e tenterà invece di aprire quei file (che sulla maggior parte dei sistemi non esistono e si otterrà un errore).
Anche la direzione del reindirizzamento non ha importanza. Sia che si utilizzi 3< /dev/tcp/...o 3> /dev/tcp/...o 3<> /dev/tcp/...o addirittura 3>> /dev/tcp/...non farà alcuna differenza, sarete in grado di leggere e scrivere da / per quel descrittore di file per ricevere i dati / inviare più di quel socket TCP.
Quando lo fai cat /dev/tcp/..., non funziona perché catnon implementa la stessa gestione speciale, fa un open("/dev/tcp/...")like per ogni file (tranne -), funziona solo la shell (solo ksh, bash) e solo per la destinazione dei reindirizzamenti.
Questo cat -è un altro esempio di un percorso di file gestito in modo speciale. Invece di fare un open("-"), legge direttamente dal descrittore di file 0 (stdin). cate molte utility di testo lo fanno, la shell non lo fa per i suoi reindirizzamenti. Per leggere il contenuto del -file, è necessario cat ./-, o cat < -(o cat - < -). Sui sistemi che non hanno /dev/stdin, bashfarà comunque qualcosa di simile per i reindirizzamenti da quel file (virtuale). GNU awkfa lo stesso per /dev/stdin, /dev/stdout, /dev/stderranche su sistemi che non dispone di tali file che possono causare qualche sorpresa su sistemi come Linux in cui i file si comportano diversamente.
zshha anche il supporto socket TCP (e flusso di dominio Unix), ma è fatto con un ztcp(e zsocket) builtin, quindi è meno limitato dell'approccio ksh / bash. In particolare, può anche fungere da server che ksh / bash non può fare. È comunque molto più limitato di quello che puoi fare in un vero linguaggio di programmazione.