Ваше запитання тісно пов'язане з тим, як оболонка, яку ви використовуєте, аналізує введення користувача в командному рядку.
Якщо першим словом у командному рядку є програма, розміщена в спеціальній папці (в основному визначається PATH), і більше ніяких спеціальних символів не дається (залежно від оболонки, яку ви використовуєте), всі наступні слова, розділені пробілами чи вкладками, передаються в програма в спеціальній формі, тобто масив. З кожним словом як одним елементом у масиві.
Як програма, яку ви збираєтеся викликати, інтерпретує аргументи (розташовані в масиві), залежить від того, як вона запрограмована. Існує кілька квазі стандартів того, як повинен виглядати синтаксис аргументів, але загалом програміст повністю вільний. Таким чином, перший аргумент можна інтерпретувати як ім'я файлу або все, що думає програміст під час написання програми.
У випадку, якщо ви додасте спеціальний символ <або >у свій командний рядок, оболонка не додає, <а >також наступні слова до масиву, який буде переданий програмі. З <або >дали запуски оболонки , щоб зробити модні речі, які підтримуються нижчого ядром (ключовим словом трубопроводу ). Щоб зрозуміти, що відбувається, ви повинні зрозуміти, що 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