Потому что это особенность оболочки (из 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. Это все еще намного более ограничено, чем то, что вы можете сделать на реальном языке программирования.