Потому что это особенность оболочки (из ksh, скопированной bash) и только оболочки.
/dev/tcp/...не являются реальными файлами, оболочка перехватывает попытки перенаправления в /dev/tcp/...файл, а затем выполняет socket(...);connect(...)(устанавливает соединение TCP) вместоopen("/dev/tcp/..."...) (открывает этот файл) в этом случае.
Обратите внимание, что это должно быть написано так. cat < /dev/./tcp/...или///dev/tcp/... не будет работать, и вместо этого попытается открыть эти файлы (которых в большинстве систем не существует, и вы получите ошибку).
Направление перенаправления также не имеет значения. Используете ли вы 3< /dev/tcp/...или 3> /dev/tcp/...или 3<> /dev/tcp/...или даже3>> /dev/tcp/... не будет никакой разницы, вы будете иметь возможность читать и писать из / в этот файловый дескриптор для приема данных / отправки через этот TCP сокет.
Когда вы это делаете cat /dev/tcp/..., это не работает, потому catчто не реализует ту же особую обработку, это делает open("/dev/tcp/...")как для каждого файла (кроме- ), только оболочка (только ksh, bash) и только для цели перенаправлений.
Это cat -еще один пример пути к файлу, который обрабатывается специально. Вместо этого open("-")он читает непосредственно из файлового дескриптора 0 (stdin). catи многие текстовые утилиты делают это, оболочка не для своих перенаправлений. Чтобы прочитать содержимое -файла, вам нужно cat ./-или cat < -(или cat - < -). Однако на системах, которые не имеют /dev/stdin, bashбудет делать нечто подобное для перенаправлений из этого (виртуального) файла. GNU awkделает то же самое /dev/stdin, /dev/stdout, /dev/stderrдаже в системах , которые имеют такие файлы , которые могут вызвать некоторые сюрпризы на системы , такие как Linux , где эти файлы ведут себя по- разному.
zshтакже имеет поддержку сокетов TCP (и потока домена Unix), но это делается с помощью встроенных ztcp(и zsocket), поэтому он менее ограничен, чем подход ksh / bash. В частности, он также может выступать в качестве сервера, чего не может сделать ksh / bash. Это все еще намного более ограничено, чем то, что вы можете сделать на реальном языке программирования.