Ваш вопрос тесно связан с тем, как используемая оболочка анализирует пользовательский ввод в командной строке.
Если первое слово в командной строке - это программа, расположенная в специальной папке (в основном определяемой как 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
качестве аргументов, но в моей системе это неSTDERR
man -l - < tee man: invalid option -- l man, version 1.6c
man
( man-db ) читает аргументыSTDIN
с заданными аргументами,-l
за которыми следует-
. Он просто интерпретирует данныеSTDIN
как справочную страницу. Для более подробного объяснения действительных аргументов и того, как они интерпретируются, вы должны обратиться к странице справки соответствующей программы. В вашем случае проконсультируйтесьman man
. Может быть, есть аналогичный вариант для васman
. Если вы хотите прочитать аргументы командной строки для конкретной программыSTDIN
xargs
(как упоминалось выше), это путь.man man
и нахожу тот, в моей ОС не поддерживает его. В любом случае, спасибо за эту декларацию этих двух концепций для меня.Они совершенно разные. Аргументы командной строки передаются программе в виде массива, и она может делать с ними все, что захочет; stdin - входной поток, из которого программа должна запрашивать данные. Программы, обрабатывающие файлы, часто выбирают поддержку обоих, но они должны делать это вручную - они проверяют, было ли передано имя файла в качестве аргумента командной строки, и если нет, то вместо этого читают из stdin
Вы, кажется, ожидаете
man
прочитать stdin, чтобы найти страницу руководства, которую он должен отобразить, что было бы очень странным поведением; когда бы ты это использовал? Тот факт, что онcat
отображает свой стандарт, является артефактом того, что он больше ничего не делает; Я не думаю, что какой-либо другой инструмент работает таким образом. Например,grep
может взять имя файла или прочитать егоstdin
, но обрабатывает данныеstdin
, не читает имя файлаstdin
и затем открывает егоЕсли вам действительно нужно это поведение, вы можете использовать
xargs
, который преобразует файл в аргументы командной строки:Или просто вставьте
cat
звонок вman
звонок:источник
man $(<file_name)
.(<>)
в цикле будет делатьSTDIN
или аргументы командной строки в качестве имен файлов ...man < file_name
состоит в том, чтобы помочь себе понять эти два понятия. Читая вам объяснение, реализация решается автором команды. Так что если я прав, тоfind
аргументы скорее обрабатывают STDIN?