Наскільки ця команда є законною? "> File1 <file2 cat"


61

Припускаючи file2, що команда вже існує

> file1 < file2 cat

як видається, копіює вміст file2у file1.

Але я не можу зрозуміти цю структуру.

Я розумію, що "Ніщо" не спрямоване на file1(створення або стирання його змісту). Потім зміст file2направляється на file1.

Чому catпісля file2? як це знати, cat file2якщо операнди не в правильному порядку?


11
Що "правильний порядок"? Чи можете ви надати посилання на якийсь ресурс / навчальний матеріал, де описано "правильне замовлення"?
Гонки легкості на орбіті

7
Задаючи подібні запитання, слід вказати оболонку; різні мають різні крайові випадки, особливо навколо перенаправлення.
chrylis -на страйк-

Відповіді:


117

Перед тим, як оболонка виконає catкоманду в командному рядку, вона шукає перенаправлення.

Є два перенаправлення:

  1. >file1 Це призведе до переходу стандартного виводу команди file1.
  2. <file2 Це зробить стандартний вхід команди file2.

Те, що ці переадресації розміщуються у неяскравому місці в командному рядку, не має значення.

$ cat <file2 >file1

те саме, що

$ <file2 cat >file1

що те саме

$ <file2 >file1 cat

тощо¹

Зауважте, що catутиліта у всіх цих екземплярах виконується без аргументів командного рядка . Перенаправлення не є операндами для catкоманди, це вказівки оболонці для встановлення переадресації в команду та вихід із неї (підключення її стандартного вводу та виводу до файлів). Оболонка встановлює перенаправлення перед викликом команди.

Різниця між cat fileі cat <file(або, якщо ви хочете <file cat) полягає в тому, що в першому випадку catутиліта сама відкриває файл для подання читання в якості операнду в командному рядку, тоді як у другому випадку оболонка буде відкрийте файл і підключіть catдо нього потік введення². У другому випадку catпомітить, що йому не було надано файлу операнду, і він автоматично перейде до зчитування зі свого стандартного вводу. Це і особливості cat, і деякі інші утиліти, а не те, що всі комунальні послуги роблять.

catтакож буде читати зі свого стандартного входу, якщо йому надано операнд -. Знову ж таки, це особливе лише для catдеяких інших утиліт (тобто нічого, що робить оболонка ). Для використання catу файлі в поточному каталозі, ім'я якого - - , додайте шлях до імені файлу, наприклад ./-.

¹ Порядок переадресацій все ще важливий за певних обставин; З cat <file2 >file1, наприклад, file1НЕ буде обрізано , якщо file2недоступний (в перепризначення обробляються зліва направо). Однак відносне розміщення слова catвсе ще довільне і на це не вплине.

² Див. Також питання " кішка дає різні помилки під час відкриття неіснуючого файлу ".


Справа в тому, що оболонка встановлює перенаправлення перед тим, як навіть виконати команду в командному рядку, тому такі речі не вдається, і ви закінчуєтесь порожнім вихідним файлом:

$ sort file >file

Тут оболонка буде усікати (порожній) файл fileперед виконанням sort fileта підключенням sortстандартного виводу до файлу. Потім sortутиліта відкриє fileі сортуватиме її вміст (що нічого). Результат (нічого) передається через стандартний вихідний потік до file.

Засіб у цьому конкретному випадку (для сортування файлу "на місці") є

$ sort -o file file

або

$ sort file >file.sorted && mv file.sorted file

що є більш-менш тим, sortщо використовується при використанні -oфайла для визначення імені вихідного файлу.


Просто для резервного копіювання твердження про те, що перенаправлення можуть передувати фактичній назві утиліти в командному рядку:

"Проста команда" - це послідовність необов'язкових присвоювань змінних та перенаправлень у будь-якій послідовності, необов'язково слідуючи за словами та перенаправленнями, завершеними оператором управління. [ref: Мова командної оболонки POSIX 2.9.1 Прості команди]

А також про перенаправлення, що не входить до операндів утиліти:

Необов'язковий номер, оператор переадресації та слово не повинні відображатися в аргументах, наданих команді, яка виконується (якщо така є). [ref: POSIX Shell Command Language 2.7 Перенаправлення]


14
@Steve Свобода переміщення переадресацій навколо може бути використана для того, щоб зробити деякі команди більш зрозумілими, як конвеєр з перенаправленням входу на початку <in foo | bar >outвстановлює все в логічному порядку. Мені також подобається, якщо echo >&2 Something bad happenedза вихід помилок із скриптів оболонки. Але >out <in catце просто обфускація

2
Як sort file >fileможна правильно виконати?
seth10

11
@setht З sort -o file file.
Kusalananda

6
Чудова відповідь. Зверніть увагу, що замовлення має значення. < file1 > file2 catбуло б краще, ніж > file2 < file1 catтак, щоб уникнути file2урізання, якщо file1його не можна відкрити.
Стефан Шазелас

3
Що слід пам’ятати: при посиланні на POSIX з фрагментами HTML, краще вказати точне видання (наприклад, pubs.opengroup.org/onlinepubs/9699919799.2016 ), оскільки відомо, що фрагменти змінюються між виданнями тієї ж редакції специфікації (багато посилань у відповідях на цьому веб-сайті, в тому числі моїх, зараз помиляються, оскільки фрагменти вказують на неправильне місце після виходу видання 2016 року).
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.