(Почти) все это файл, но не все это обычный файл. Не имеет смысла вызывать текстовый редактор для чего-то особенного, такого как каталог, сетевой сокет, последовательный порт и т. Д.
Файл /dev/stdoutможет быть одним из нескольких в зависимости от варианта Unix:
- «специальный» файл, обычно символьное устройство;
- «магическая» символическая ссылка, указывающая на файл, который процесс, обращающийся к нему, открыл в этом дескрипторе;
- символическая ссылка на один из вышеперечисленных.
В любом случае при открытии /dev/stdoutи аналогичных файлах создается новый файловый дескриптор, связанный с тем же файлом, который приложение уже открыло в файловом дескрипторе 1. «Стандартный вывод» означает файловый дескриптор 1, и этот дескриптор файла используется только в соответствии с соглашением для вывода - ядру все равно.
Когда вы запускаете программу в терминале, на терминальном устройстве открываются все три стандартных дескриптора (0 = стандартный ввод, 1 = стандартный вывод, 2 = стандартная ошибка). Чтение с этого устройства возвращает символы, набранные пользователем, а запись на это устройство отображает текст в окне терминала. (Для терминального устройства нет стандартного способа прочитать вывод, который он отображает, или ввести ввод в него.)
Когда вы запускаете cat /dev/stdout, это делает то же самое, что и cat /dev/stdinor cat /dev/stderr, потому что эти три файловых дескриптора подключены к одному и тому же файлу: он сообщает catо необходимости чтения из терминала. Это то, что catбез аргументов тоже.
Если вы запустили cat /dev/stdout >foo, то /dev/stdoutобратились бы к файлу foo- эта команда эквивалентна cat foo >foo. В зависимости от catреализации, он может либо выдавать ошибку (версия GNU жалуется, что «входной файл является выходным файлом»), либо может ничего не делать, потому что читает из fooпустого файла ( >fooпросто обрезает его). С версией cat, которая не обнаруживает этот особый случай, если fooон не пустой, то cat /dev/stdout >>fooили эквивалент cat foo >>fooбудет добавлять содержимое файла к себе на неопределенный срок.
Когда вы запускаете vim /dev/stdout, он жалуется, потому что не знает, как редактировать терминал (это просто не имеет смысла).