В вычислениях, перенаправление - это форма межпроцессного взаимодействия и функция, общая для большинства интерпретаторов командной строки, включая различные оболочки Unix, которые могут перенаправлять стандартные потоки в указанные пользователем местоположения.
В Unix-подобных операционных системах программы выполняют перенаправление с помощью системного вызова dup2 (2) или его менее гибкого, но более высокого -level stdio аналоги, freopen (3) и (3).
Перенаправление обычно реализуется путем размещения определенных символов между команды.
Обычно синтаксис этих символов выглядит следующим образом: <
используется для перенаправления ввода, а >
- для перенаправления вывода. command>file1
выполняет command1, помещая вывод в file1, в отличие от отображения его на терминале, который является обычным местом назначения для стандартного вывода. Это затирает любые существующие данные в файле1.
Использование command < file1
выполняет command1 с file1 в качестве источника ввода, в отличие от keyboard, который является обычным источником для стандартных ввод.
command < infile>outfile
объединяет две возможности: command1 читает из infile и записывает в outfile
для добавления вывода в конец файла, вместо того, чтобы затирать его, используется оператор >>
: command1>>file1
.
Для чтения из потокового литерала (встроенного файла, переданного на стандартный ввод), здесь можно использовать документ, используя оператор <<
:
$ tr az AZ << END_TEXT>one two three>uno dos tres>END_TEXT ONE TWO THREE UNO DOS TRES
Для чтения из строки можно использовать здесь строку, используя оператор <<<
: tr az AZ <<< "one two three"
, или:
$ NUMBERS = "one two three" $ tr az AZ <<< "$NUMBERS" ONE TWO THREE
Программы могут запускаться вместе, так что одна программа считывает вывод из другой без необходимости в явном промежуточном файле. command1 | command2
выполняет command1, используя его выходные данные в качестве входных для command2 (обычно называемого piping, с символом «|
», известным как «pipe ").
Две программы, выполняющие команды, могут работать параллельно, при этом единственное пространство хранения - это рабочие буферы (Linux позволяет до 64 КБ для каждого буфера) плюс любое рабочее пространство, необходимое для обработки каждой команды. Например, команда «sort» не может производить какой-либо вывод, пока не будут прочитаны все входные записи, так как самая последняя полученная запись может оказаться первой в отсортированном порядке. Экспериментальная операционная система доктора Алексии Массалин, Synthesis, могла регулировать приоритет каждой задачи во время ее выполнения в соответствии с заполненностью их входных и выходных буферов.
Это дает тот же конечный результат, что и при использовании двух перенаправлений и временного файла, например:
$ command1>tempfile $ command2 < tempfile $ rm tempfile
Но здесь command2 не начинает выполняться до command1 завершена, и требуется достаточно большой рабочий файл для хранения промежуточных результатов, а также любое рабочее пространство, необходимое для каждой задачи. Например, хотя DOS допускает «конвейерный» синтаксис, он использует второй подход. Таким образом, предположим, что некоторая долго работающая программа «Worker» создает различные сообщения во время работы, и что вторая программа, TimeStamp, копирует каждую запись из stdin в stdout с префиксом системной даты и времени, когда запись получена. Последовательность, например Рабочий | TimeStamp>LogFile.txt
будет выдавать временные метки только после завершения Worker, просто показывая, насколько быстро его выходной файл может быть прочитан и записан.
Хорошим примером конвейерной передачи команд является объединение echo
с другой командой для достижения чего-то интерактивного в неинтерактивной оболочке, например echo -e 'пользователь \ npass' | ftp localhost
. Это запускает клиент ftp с входным пользователем, нажмите return, затем pass.
При обычном использовании начальным шагом конвейера часто является cat
или echo
, чтение из файла или строки. Часто это можно заменить косвенным указанием ввода или здесь строкой, а использование cat и piping вместо перенаправления ввода известно как бесполезное использование cat. Например, следующие команды:
$ cat infile | команда $ echo $ строка | команда $ echo -e 'пользователь \ npass' | ftp localhost
можно заменить на:
$ command < infile $ command <<< $string $ ftp localhost <<< $'user\npass'
Поскольку echo
часто является внутренней командой оболочки, ее использование не так критикуется, как cat, которая является внешней командой.
В оболочках Unix, производных от исходной оболочки Bourne, первые два действия могут быть дополнительно изменены помещая число (дескриптор файла ) непосредственно перед символом ; это повлияет на то, какой поток используется для перенаправления. Стандартные потоки ввода-вывода Unix:
Handle | Name | Описание |
---|---|---|
0 | stdin | Стандартный ввод |
1 | stdout | Стандартный вывод |
2 | stderr | Стандартная ошибка |
Например, команда 2>file1
выполняет команду, направляя поток стандартной ошибки в file1.
В оболочках, производных от csh (оболочка C ), вместо этого синтаксис добавляет символ (амперсанд) к символам перенаправления, таким образом аналогичный результат. Причина этого заключается в том, чтобы различать файл с именем '1' и стандартный вывод, то есть cat file 2>1
vs cat file 2>1
. В первом случае stderr перенаправляется в файл с именем «1», а во втором - stderr перенаправляется на стандартный вывод.
Еще одна полезная возможность - перенаправить один стандартный дескриптор файла на другой. Самый популярный вариант - объединить стандартную ошибку в стандартный вывод, чтобы сообщения об ошибках можно было обрабатывать вместе (или поочередно) с обычным выводом. Например, find / -name.profile>results 2>1
попытается найти все файлы с именем.profile. Выполненный без перенаправления, он будет выводить попадания в stdout и ошибки (например, из-за отсутствия прав на просмотр защищенных каталогов) в stderr. Если стандартный вывод направляется в файл результатов, на консоли появляются сообщения об ошибках. Чтобы увидеть совпадения и сообщения об ошибках в результатах файла, объедините stderr (дескриптор 2) в stdout (дескриптор 1), используя 2>1
.
. объединенный вывод должен быть передан в другую программу, последовательность объединения файлов 2>1
должна предшествовать символу вертикальной черты, таким образом, find / -name.profile 2>1 | less
Упрощенная, но не соответствующая POSIX форма команды, command>file 2>1
(недоступна в Bourne Shell до версии 4, окончательный выпуск, или в стандартной оболочке Оболочка Debian Almquist, используемая в Debian / Ubuntu): команда>файл
или команда>файл
.
Можно использовать 2>1
перед " >
", но результат обычно понимается неправильно. Правило состоит в том, что любое перенаправление устанавливает дескриптор выходного потока независимо. Итак, «2>1
» устанавливает дескриптор 2
на любой дескриптор, на который указывает 1
, который в этой точке обычно является стандартным выводом. Затем «>
» перенаправляет дескриптор 1
на что-то другое, например файл, но он не изменяет дескриптор 2
, который по-прежнему указывает на стандартный вывод.
В следующем примере стандартный вывод записывается в файл, но ошибки перенаправляются со стандартного вывода на стандартный вывод, то есть отправляются на экран: команда 2>1>файл
.
Для записи как ошибок, так и стандартный вывод в файл, порядок должен быть обратным. Стандартный вывод сначала будет перенаправлен в файл, затем stderr будет дополнительно перенаправлен на дескриптор stdout, который уже был изменен, чтобы указывать на файл: command>file 2>1
.
Токены перенаправления и конвейера можно объединять в цепочку для создания сложных команд. Например, sort infile | uniq -c | sort -n>outfile
сортирует строки файла infile в лексикографическом порядке, записывает уникальные строки с префиксом по количеству вхождений, сортирует результирующий вывод численно и помещает окончательный вывод в файл вывода. Этот тип конструкции очень часто используется в сценариях оболочки и пакетных файлах.
Стандартная команда tee может перенаправить вывод команды в несколько пунктов назначения: ls -lrt | тройник xyz
. Это направляет вывод списка файлов как в стандартный вывод, так и в файл xyz.
dup
: дублировать дескриптор открытого файла - Справочник по системным интерфейсам, Единая спецификация UNIX, выпуск 7 из Открытая группа