Прежде чем оболочка выполнит 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 Перенаправление]