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