Ваше запитання тісно пов'язане з тим, як оболонка, яку ви використовуєте, аналізує введення користувача в командному рядку.
Якщо першим словом у командному рядку є програма, розміщена в спеціальній папці (в основному визначається 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