Ваш вопрос тесно связан с тем, как используемая оболочка анализирует пользовательский ввод в командной строке.
Если первое слово в командной строке - это программа, расположенная в специальной папке (в основном определяемой как PATH), и больше не вводятся специальные символы (в зависимости от используемой вами оболочки), все последующие слова, разделенные пробелами или символами табуляции, передаются в программа в специальной форме т.е. массив. С каждым словом в качестве одного элемента в массиве.
То, как программа, которую вы собираетесь вызывать, интерпретирует аргументы (расположенные в массиве), зависит от того, как она запрограммирована. Существует несколько квази-стандартов того, как должен выглядеть синтаксис аргументов, но в целом программист полностью свободен. Таким образом, первый аргумент может быть интерпретирован как имя файла или то, о чем думал программист во время написания программы.
В случае, если вы добавите специальный символ <или >в командную строку, оболочка не добавит <и >ни последующие слова в массив, который будет передан программе. При наличии <или >задании оболочка начинает делать причудливые вещи, поддерживаемые базовым ядром (ключевое слово piping ). Чтобы понять, что происходит, вы должны понимать, что STDINи STDOUT(поскольку это не связано непосредственно, я опускаю STDERR).
Все, что вы видите на своем терминале (в большинстве случаев это часть вашего дисплея), либо написано оболочкой, либо любой другой программой, которую вы ранее вызывали, в специальный файл (в unix все является файлом ). Этот файл имеет специальный идентификатор и называется STDOUT. Если программа хочет считывать данные с клавиатуры, она не запрашивает клавиатуру напрямую (по крайней мере, в большинстве случаев), а читает из специального файла с именем STDIN. Внутренне этот файл подключен к вашему стандартному устройству ввода, в большинстве случаев к вашей клавиатуре.
Если оболочка читает <или >в разобранной командной строке, она манипулирует STDINили STDOUTв определенном виде во время выполнения соответствующей программы. STDINи больше не STDOUTуказывает на терминал или стандартное устройство ввода, а на последующее имя файла в командной строке.
В случае двух линий
cat file_name
cat < file_name
наблюдаемое поведение идентично, потому что соответствующий разработчик заставляет catлибо читать данные, STDINлибо читать данные из файла, чье имя задается в качестве первого аргумента командной строки (который является первым элементом в массиве, в который оболочка передает cat). Впоследствии catзаписывает весь контент file_nameили STDINв терминал, так как мы не инструктируем оболочку манипулировать STDOUT. Помните, что во второй строке ваша оболочка манипулирует STDINтаким образом, что она больше не указывает на ваше стандартное устройство ввода, а указывает на файл, называемый file_nameв вашем текущем рабочем каталоге.
В другом случае линии
man < file_name
manне предназначен для чтения чего-либо, STDINесли он вызывается без аргумента, т.е. с пустым массивом. Итак, линия
man < file_name
равно
man
Например, manбудет читать что-то из STDINтоже, если вы переходите -l -к man. С помощью этой опции, заданной в командной строке, вы можете отображать содержимое всего, что manсчитывается с STDINвашего терминала. Так
man -l - < file_name
будет также работать (но будьте осторожны, manэто не только пейджер, но и анализирует входные данные файла, поэтому содержимое файла и отображаемое содержимое могут отличаться).
Так как STDIN, STDOUTи аргументы командной строки интерпретируются все до соответствующего разработчика.
Я надеюсь, что мой ответ может прояснить ситуацию.
man -l - < file_nameдля созданияmanинтерпретаций вSTDINкачестве аргументов, но в моей системе это неSTDERRman -l - < tee man: invalid option -- l man, version 1.6c