Прежде чем оболочка выполнит cat
команду в командной строке, она ищет перенаправления.
Есть два перенаправления:
>file1
Это заставит стандартный вывод команды перейти на file1
.
<file2
Это сделает стандартный ввод команды из file2
.
Тот факт, что эти перенаправления размещаются в неудобном месте в командной строке, не имеет значения.
$ cat <file2 >file1
такой же как
$ <file2 cat >file1
который так же, как
$ <file2 >file1 cat
etc.¹
Обратите внимание, что cat
утилита во всех этих случаях выполняется без аргументов командной строки . Перенаправления не являются операндами cat
команды, они представляют собой инструкции для оболочки по настройке перенаправлений в команду и из нее (соединяя ее стандартный ввод и вывод с файлами). Оболочка устанавливает перенаправления перед вызовом команды.
Разница между cat file
и cat <file
(или, если хотите, <file cat
) заключается в том, что в первом случае cat
утилита сама открывает файл, который задается как операнд в командной строке, для чтения, а во втором случае оболочка будет откройте файл и подключите cat
к нему поток ввода². Во втором случае cat
заметит, что ему не был предоставлен файловый операнд, и автоматически переключится на чтение со своего стандартного ввода. Это особенность cat
некоторых других утилит, а не то, что делают все утилиты.
cat
также будет читать со своего стандартного ввода, если ему дан операнд -
. Опять же, это особенное только для cat
некоторых других утилит (то есть ничего, что делает оболочка ). Для использования cat
на файл в текущем каталоге, имя которого является -
, добавить путь к имени файла, например ./-
.
Order Порядок перенаправлений по-прежнему важен при некоторых обстоятельствах; С cat <file2 >file1
, например, file1
не будет усечено, если file2
недоступно (перенаправления анализируются слева направо). Относительное размещение слова cat
все же произвольно и не повлияет на это.
² См. Также вопрос « 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 Shell Command Language 2.9.1 Простые команды]
А также о том, что перенаправление не является частью операндов утилиты:
Необязательный номер, оператор перенаправления и слово не должны появляться в аргументах, предоставляемых команде, которая будет выполнена (если есть). [ref: Язык команд оболочки POSIX 2.7 Перенаправление]