Перенаправление потоков ввода вывода windows. Создание собственного перенаправления вывода

Бытовая техника 15.06.2019

Операторы перенаправления команд используются для изменения местоположений потоков ввода и вывода команд, заданных по умолчанию, на какие-либо другие. Местоположение потоков ввода и вывода называется дескриптор.

В следующей таблице описаны операторы перенаправления потоков ввода и вывода команд.

Оператор перенаправления Описание
> Записывает данные на выходе команды вместо командной строки в файл или на устройство, например, на принтер.
< Читает поток входных данных команды из файла, а не с клавиатуры.
>> Добавляет выходные данные команды в конец файла, не удаляя при этом существующей информации из файла.
>& Считывает данные на выходе одного дескриптора как входные данные для другого дескриптора.
<& Считывает входные данные одного дескриптора как выходные данные другого дескриптора.
| Считывает выходные данные одной команды и записывает их на вход другой команды. Эта процедура известна под названием «канал».

По умолчанию, входные данные команды (дескриптор STDIN) отсылаются с клавиатуры интерпретатору команд Cmd.exe, далее Cmd.exe отправляет выходные данные команды (дескриптор STDOUT) в окно командной строки.

В следующей таблице представлены доступные дескрипторы.

Номера от 0 до 9 представляют первые 10 дескрипторов. Для запуска программы и перенаправления любого из 10 дескрипторов используется интерпретатор команд Cmd.exe. Для задания требуемого дескриптора перед оператором перенаправления введите его номер. Если дескриптор не определен, то по умолчанию оператором перенаправления ввода «<» будет ноль (0), а оператором перенаправления вывода «>» будет единица (1). После ввода оператора «<» или «>» необходимо указать, откуда читать и куда записывать данные. Можно задать имя файла или любой из существующих дескрипторов.

Для задания перенаправления в существующие дескрипторы используется амперсанд (&), затем номер требуемого дескриптора (например, & номер_дескриптора ). Например, для перенаправления дескриптора 2 (STDERR) в дескриптор 1 (STDOUT) введите:

Дублирование дескрипторов

Оператор перенаправления «&» дублирует выходные или входные данные с одного заданного дескриптора на другой заданный дескриптор. Например, для отправки выводных данных команды dir в файл File.txt и отправки ошибки вывода в файл File.txt введите:

dir>c:\file.txt 2>&1

При дублировании дескриптора происходит копирование всех его исходных характеристик. Например, если дескриптор доступен только для записи, то все его дубликаты будут доступны только для записи. Нельзя продублировать дескриптор с доступом только для чтения в дескриптор с доступом только для записи.

Перенаправление ввода команд (<)

Для перенаправления ввода команд с цифровой клавиатуры на файл или на устройство используйте оператор «<». Например, для ввода команды sort из файла List.txt введите:

sort

Содержимое файла File.txt появится в командной строке в виде списка в алфавитном порядке.

Оператор «<» открывает заданное имя файла с доступом только для чтения. Поэтому с его помощью нельзя записывать в файл. Например, при запуске программы с оператором <&2 все попытки прочитать дескриптор 0 ни к чему не приведут, так как изначально он был открыт с доступом только для записи.

Примечание

  • Дескриптор 0 задан по умолчанию для оператора перенаправления ввода «<».

Перенаправление вывода команд (>)

Выходные данные практически всех команд высвечиваются в окне командной строки. Даже команды, выводящие данные на диск или принтер, выдают сообщения и запросы в окне командной строки.

Для перенаправления вывода команд из окна командной строки в файл или на устройство применяется оператор «>». Этот оператор используется с большинством команд. Например, для перенаправления вывода команды dir в файл Dirlist.txt введите:

dir>dirlist.txt

Если файл Dirlist.txt не существует, интерпретатор команд Cmd.exe создаст его. Если файл существует, Cmd.exe заменит информацию в файле на данные, полученные от команды dir .

Для запуска команды netsh routing dump и последующей отправки результатов ее работы в Route.cfg введите:

netsh routing dump > c:\route.cfg

Оператор «>» открывает заданный файл с доступом только для записи. Поэтому с помощью данного оператора файл прочитать нельзя. Например, при запуске программы с оператором перенаправления <&0 все попытки записать дескриптор 1 ни к чему не приведут, так как изначально дескриптор 0 был открыт с доступом только для чтения.

Примечание.

  • Дескриптор 1 задан по умолчанию для оператора перенаправления вывода «>».

Использование оператора «<&» для перенаправления ввода и дублирования

Для использования оператора перенаправления ввода необходимо, чтобы задаваемый файл уже существовал. Если файл для ввода существует, то интерпретатор команд Cmd.exe открывает его с доступом только для чтения и его содержимое отправляет в команду так, как если бы это был ввод с цифровой клавиатуры. При задании дескриптора интерпретатор команд Cmd.exe дублирует его в дескриптор, существующий в системе.

Например, для считывания файла File.txt на вход в дескриптор 0 (STDIN) введите:

Для открытия файла File.txt, сортировки его содержимого и последующей отправки в окно командной строки (STDOUT) введите:

sort< file.txt

Для того чтобы найти файл File.txt и перенаправить дескриптор 1 (STDOUT) и дескриптор 2 (STDERR) в Search.txt введите:

findfile file.txt>search.txt 2<&1

Для дублирования определенного пользователем дескриптора 3 в качестве входной информации для дескриптора 0 (STDIN) введите:

Использование оператора «>&» для перенаправления ввода и дублирования

При перенаправлении вывода в файл и задании существующего имени файла интерпретатор команд Cmd.exe открывает файл с доступом только для записи и переписывает его содержимое. Если дескриптор задан, интерпретатор команд Cmd.exe дублирует файл в существующий дескриптор.

Для дублирования определенного пользователем дескриптора 3 в дескриптор 1 введите:


Для перенаправления всех выходных данных, включая выходные данные дескриптора 2 (STDERR), команды ipconfig в дескриптор 1 (STDOUT) и последующего перенаправления выходных данных в Output.log введите:


ipconfig.exe>>output.log 2>&1

Использование оператора «>>» для добавления вывода

Для добавления выходных данных команды в конец файла без потери хранящейся в нем информации используется двойной символ «больше» (>>). Например, следующая команда добавляет список каталогов, созданный командой dir , в файл Dirlist.txt:


dir>>dirlist.txt

Для добавления выходных данных команды netstat в конец файла Tcpinfo.txt введите:


netstat>>tcpinfo.txt

Иногда удобнее записывать это следующим образом:

SET OutFile="%~n0.html" > %OutFile% ECHO ^ >> %OutFile% ECHO ^ >> %OutFile% ECHO ^best page^ >> %OutFile% ECHO ^ >> %OutFile% ECHO ^ >> %OutFile% ECHO Hello World >> %OutFile% ECHO ^ >> %OutFile% ECHO ^

Использование оператора канала (|)

Оператор канала «вертикальная линия» (|) забирает выходные данные одной команды (по умолчанию STDOUT) и направляет их на вход другой команды (по умолчанию STDIN). Например, следующая команда сортирует каталог:

В данном примере обе команды запускаются одновременно, но команда sort приостанавливает работу до получения выходных данных команды dir . Команда sort использует выходные данные команды dir в качестве своих входных данных, а затем свои выходные данные отправляет в дескриптор 1 (STDOUT).

Комбинирование команд с операторами перенаправления

Комбинируя команды-фильтры с другими командами и именами файлов, можно создавать команды на заказ. Например, для сохранения имен файлов, содержащих строку «LOG», используется следующая команда:

dir /b | find "LOG" > loglist.txt

Выход команды dir отсылается в команду-фильтр find . Имена файлов, содержащие строку «LOG», хранятся в файле Loglist.txt в виде списка (например, NetshConfig.log, Logdat.svd и Mylog.bat).

При использовании более одного фильтра в одной команде их необходимо отделять с помощью канала (|). Например, следующая команда ищет в каждом каталоге диска C файлы, в названии которых присутствует строка «Log», и выводит их постранично на экран:

dir c:\ /s /b | find "LOG" | more

Наличие канала (|) указывает cmd.exe , что выход команды DIR нужно отправить команде-фильтру find . Команда find выбирает только те имена файлов, в которых содержится строка «LOG». Команда more выводит на экран имена файлов, полученные командой find с паузой после заполнения каждого экрана. Дополнительные сведения о командах-фильтрах смотри в разделе

Доброго времени, читатели моего !
В данной статье хочу систематизировать свои знания по основным принципам работы программных потоков и каналов в интерпретаторе и в общем в ОС Linux, а так же о возможностях перенаправления данных потоков .
В самом начале хочу отметить, что интерпретатор работает с тремя стандартными потоками:

  1. stdout это стандартный поток вывода , который обеспечивает вывод команды. Дескриптор потока равен 1.
  2. stderr это стандартный поток ошибок , который выводит ошибки команд. Его дескриптор равен 2.
  3. stdin это стандартный поток ввода , который обеспечивает ввод командам. Его дескриптор равен 0.

Теперь простыми словами опишем, что эти три пункта обозначают:

stdout - стандартный поток вывода. Это, говоря простым языком, та информация, которую мы видим в интерпретаторе при выполнении команд. То есть все сообщения (без сообщений об ошибках), которые выполняемая в интерпретаторе команда сообщает и выводит на терминал (читай - экран). (вывод на экран задан по умолчанию, но можно указать и вывод, например в файл или перенаправление в другую команду, как это делается, расскажу ниже)

stderr - поток ошибок. Это ошибки при выполнении команд в bash, которые по умолчанию выводятся на stdout, то есть на терминал (опять же, если не указан вывод в другое место)

stdin - поток ввода. Это, говоря простым языком - то, что мы вводим с клавиатуры в интерпретатор для выполнения команды.

Очень хорошо данные потоки изображены на рисунке, взятом с http://rus-linux.net/:

На данном изображении: Stdin , показан зеленым, имеет дескриптор 0
Stdout , показан красным, имеет дескриптор 1
Stderr , показан синим, имеет дескриптор 2

Далее расскажу, как данные потоки можно перенаправить в/из файл. То есть при выполнении команды, чтобы сообщения или ошибки выводились не на экран, а записывались в файл. Для чего это нужно? Ну например вы выполняете какую-то команду, у которой вывод не помещается в окно терминала. Вы указываете сохранять стандартный вывод в один файл, а стандартный поток ошибок в другой. Тем самым, все ошибки и если нужно стандартный вывод, можно будет посмотреть подробно, открыв сохраненные файлы.

Итак, перенаправление потоков выполняется следующим образом:

$ command n>file

В данной строке показано: выполнение команды command и перенаправление потока (где n = дескриптору потока) в файл file. При выполнении данного перенаправления, если конечный файл существует, он будет перезаписан . При этом, если n не указан, то предполагается стандартный вывод.

$ command n>>file

Данная команда имеет аналогичный синтаксис, но тут указан символ ">>". При данном перенаправлении, если конечный файл существует, то вывод команды будет добавлен к имеющимся данным.

$ command < file

в данном примере команда command выполняется и использует в качестве источника ввода, файл file, вместо ввода с клавиатуры

Иногда возникает необходимость объединить стандартный поток ошибок со стандартным потоком вывода, чтобы можно было обрабатывать ошибки и обычные результаты работы программы вместе. для этих целей используется комбинация с символом: &. Пример выполнения данного действия:

Find / -name .name_file > /path/to/file 2>&1

При выполнении данной команды, происходит поиск файла от корня файловой системы с именем .name_file и перенаправление результатов поиска (stdout и stderr) в файл /path/to/file . Конструкция > /path/to/file 2>&1 перенаправляет стандартный вывод в /path/to/file и вывод ошибок в стандартный вывод. При этом: написание 2>&1 перед > не будет работать, так как когда интерпретатор прочитает 2>&1 , он еще не знает куда перенаправлен стандартный поток вывода, поэтому потоки ошибок и вывода не будут объединены.

$ command > file 2>&1

аналогична написанию:

$ command &> file

$ command 2>&file

Если необходимо проигнорировать вывод, его можно направить в устройство /dev/null, это своего рода "черная дыра", принимающая любое количество информации и превращающая ее в ничто.

Думаю приведенной информации о перенаправлении потоко будет достаточно для понимания сути, теперь расскажу о конвеерной передаче .

Конвеер в Linux - это возможность нескольких программ работать совместно, когда выход одной программы непосредственно передается на вход другой без использования промежуточных временных файлов. Синтаксис использования конвеера следующий:

$ command1 | command2

В данном примере выполняется команда command1 , ее поток вывода используется, как поток ввода при выполнении command2 .

На сегодня все. Буду рад комментариям и дополнениям. Спасибо.

С Уважением, Mc.Sim!

  • Перевод

Если вы уже освоились с основами терминала, возможно, вы уже готовы к тому, чтобы комбинировать изученные команды. Иногда выполнения команд оболочки по одной вполне достаточно для решения некоей задачи, но в некоторых случаях вводить команду за командой слишком утомительно и нерационально. В подобной ситуации нам пригодятся некоторые особые символы, вроде угловых скобок.

Для оболочки, интерпретатора команд Linux, эти дополнительные символы - не пустая трата места на экране. Они - мощные команды, которые могут связывать воедино различные фрагменты информации, разделять то, что было до этого цельным, и делать ещё много всего. Одна из самых простых, и, в то же время, мощных и широко используемых возможностей оболочки - это перенаправление стандартных потоков ввода/вывода.

Три стандартных потока ввода/вывода

Для того, чтобы понять то, о чём мы будем тут говорить, важно знать, откуда берутся данные, которые можно перенаправлять, и куда они идут. В Linux существует три стандартных потока ввода/вывода данных.

Первый - это стандартный поток ввода (standard input). В системе это - поток №0 (так как в компьютерах счёт обычно начинается с нуля). Номера потоков ещё называют дескрипторами. Этот поток представляет собой некую информацию, передаваемую в терминал, в частности - инструкции, переданные в оболочку для выполнения. Обычно данные в этот поток попадают в ходе ввода их пользователем с клавиатуры.

Второй поток - это стандартный поток вывода (standard output), ему присвоен номер 1. Это поток данных, которые оболочка выводит после выполнения каких-то действий. Обычно эти данные попадают в то же окно терминала, где была введена команда, вызвавшая их появление.

И, наконец, третий поток - это стандартный поток ошибок (standard error), он имеет дескриптор 2. Этот поток похож на стандартный поток вывода, так как обычно то, что в него попадает, оказывается на экране терминала. Однако, он, по своей сути, отличается от стандартного вывода, как результат, этими потоками, при желании, можно управлять раздельно. Это полезно, например, в следующей ситуации. Есть команда, которая обрабатывает большой объём данных, выполняя сложную и подверженную ошибкам операцию. Нужно, чтобы полезные данные, которые генерирует эта команда, не смешивались с сообщениями об ошибках. Реализуется это благодаря раздельному перенаправлению потоков вывода и ошибок.

Как вы, вероятно, уже догадались, перенаправление ввода/вывода означает работу с вышеописанными потоками и перенаправление данных туда, куда нужно программисту. Делается это с использованием символов > и < в различных комбинациях, применение которых зависит от того, куда, в итоге, должны попасть перенаправляемые данные.

Перенаправление стандартного потока вывода

Предположим, вы хотите создать файл, в который будут записаны текущие дата и время. Дело упрощает то, что имеется команда, удачно названная date , которая возвращает то, что нам нужно. Обычно команды выводят данные в стандартный поток вывода. Для того, чтобы эти данные оказались в файле, нужно добавить символ > после команды, перед именем целевого файла. До и после > надо поставить пробел.

При использовании перенаправления любой файл, указанный после > будет перезаписан. Если в файле нет ничего ценного и его содержимое можно потерять, в нашей конструкции допустимо использовать уже существующий файл. Обычно же лучше использовать в подобном случае имя файла, которого пока не существует. Этот файл будет создан после выполнения команды. Назовём его date.txt . Расширение файла после точки обычно особой роли не играет, но расширения помогают поддерживать порядок. Итак, вот наша команда:

$ date > date.txt
Нельзя сказать, что сама по себе эта команда невероятно полезна, однако, основываясь на ней, мы уже можем сделать что-то более интересное. Скажем, вы хотите узнать, как меняются маршруты вашего трафика, идущего через интернет к некоей конечной точке, ежедневно записывая соответствующие данные. В решении этой задачи поможет команда traceroute , которая сообщает подробности о маршруте трафика между нашим компьютером и конечной точкой, задаваемой при вызове команды в виде URL. Данные включают в себя сведения обо всех маршрутизаторах, через которые проходит трафик.

Так как файл с датой у нас уже есть, будет вполне оправдано просто присоединить к этому файлу данные, полученные от traceroute . Для того, чтобы это сделать, надо использовать два символа > , поставленные один за другим. В результате новая команда, перенаправляющая вывод в файл, но не перезаписывающая его, а добавляющая новые данные после старых, будет выглядеть так:

$ traceroute google.com >> date.txt
Теперь нам осталось лишь изменить имя файла на что-нибудь более осмысленное, используя команду mv , которой, в качестве первого аргумента, передаётся исходное имя файла, а в качестве второго - новое:

$ mv date.txt trace1.txt

Перенаправление стандартного потока ввода

Используя знак < вместо > мы можем перенаправить стандартный ввод, заменив его содержимым файла.

Предположим, имеется два файла: list1.txt и list2.txt , каждый из которых содержит неотсортированный список строк. В каждом из списков имеются уникальные для него элементы, но некоторые из элементов список совпадают. Мы можем найти строки, которые имеются и в первом, и во втором списках, применив команду comm , но прежде чем её использовать, списки надо отсортировать.

Существует команда sort , которая возвращает отсортированный список в терминал, не сохраняя отсортированные данные в файл, из которого они были взяты. Можно отправить отсортированную версию каждого списка в новый файл, используя команду > , а затем воспользоваться командой comm . Однако, такой подход потребует как минимум двух команд, хотя то же самое можно сделать в одной строке, не создавая при этом ненужных файлов.

Итак, мы можем воспользоваться командой < для перенаправления отсортированной версии каждого файла команде comm . Вот что у нас получилось:

$ comm <(sort list1.txt) <(sort list2.txt)
Круглые скобки тут имеют тот же смысл, что и в математике. Оболочка сначала обрабатывает команды в скобках, а затем всё остальное. В нашем примере сначала производится сортировка строк из файлов, а потом то, что получилось, передаётся команде comm , которая затем выводит результат сравнения списков.

Перенаправление стандартного потока ошибок

И, наконец, поговорим о перенаправлении стандартного потока ошибок. Это может понадобиться, например, для создания лог-файлов с ошибками или объединения в одном файле сообщений об ошибках и возвращённых некоей командой данных.

Например, что если надо провести поиск во всей системе сведений о беспроводных интерфейсах, которые доступны пользователям, у которых нет прав суперпользователя? Для того, чтобы это сделать, можно воспользоваться мощной командой find .

Обычно, когда обычный пользователь запускает команду find по всей системе, она выводит в терминал и полезные данные и ошибки. При этом, последних обычно больше, чем первых, что усложняет нахождение в выводе команды того, что нужно. Решить эту проблему довольно просто: достаточно перенаправить стандартный поток ошибок в файл, используя команду 2> (напомним, 2 - это дескриптор стандартного потока ошибок). В результате на экран попадёт только то, что команда отправляет в стандартный вывод:

$ find / -name wireless 2> denied.txt
Как быть, если нужно сохранить результаты работы команды в отдельный файл, не смешивая эти данные со сведениями об ошибках? Так как потоки можно перенаправлять независимо друг от друга, в конец нашей конструкции можно добавить команду перенаправления стандартного потока вывода в файл:

$ find / -name wireless 2> denied.txt > found.txt
Обратите внимание на то, что первая угловая скобка идёт с номером - 2> , а вторая без него. Это так из-за того, что стандартный вывод имеет дескриптор 1, и команда > подразумевает перенаправление стандартного вывода, если номер дескриптора не указан.

И, наконец, если нужно, чтобы всё, что выведет команда, попало в один файл, можно перенаправить оба потока в одно и то же место, воспользовавшись командой &> :

$ find / -name wireless &> results.txt

Итоги

Тут мы разобрали лишь основы механизма перенаправления потоков в интерпретаторе командной строки Linux, однако даже то немногое, что вы сегодня узнали, даёт вам практически неограниченные возможности. И, кстати, как и всё остальное, что касается работы в терминале, освоение перенаправления потоков требует практики. Поэтому рекомендуем вам приступить к собственным экспериментам с > и < .

Уважаемые читатели! Знаете ли вы интересные примеры использования перенаправления потоков в Linux, которые помогут новичкам лучше освоиться с этим приёмом работы в терминале?

Для того, чтобы записать данные в файл или прочитать их оттуда, процессу необходимо сначала открыть этот файл (при открытии на запись, возможно, придётся предварительно создать его). При этом процесс получает дескриптор (описатель) открытого файла - уникальное для этого процесса число, которое он и будет использовать во всех операциях записи. Первый открытый файл получит дескриптор, второй - 1 и так далее. Закончив работу с файлом, процесс закрывает его, при этом дескриптор освобождается и может быть использован повторно. Если процесс завершается, не закрыв файлы, за него это делает система. Строго говоря, только в операции открытия дескриптора указывается, какой именно файл будет использоваться. В качестве «файла» используются и обычные файлы, и файлы-дырки (чаще всего - терминалы), и каналы , описанные в разделе Pipeline..Конвейер. Дальнейшие операции - чтение, запись и закрытие, работают с дескриптором, как с потоком данных , а куда именно ведёт этот поток, неважно.

Каждый процесс Linux получает при старте три «файла», открытых для него системой. Первый из них (дескриптор) открыт на чтение , это стандартный ввод процесса. Именно со стандартным вводом работают все операции чтения, если в них не указан дескриптор файла. Второй (дескриптор 1) - открыт на запись, это стандартный вывод процесса. С ним работают все операции записи, если дескриптор файла не указан в них явно. Наконец, третий поток данных (дескриптор 2) предназначается для вывода диагностических сообщений, он называется стандартный вывод ошибок . Поскольку эти три дескриптора уже открыты к моменту запуска процесса, первый файл, открытый самим процессом, будет, скорее всего, иметь дескриптор 3 .

Дескриптор Описатель потока данных, открытого процессом. Дескрипторы нумеруются начиная с. При открытии нового потока данных его дескриптор получает наименьший из неиспользуемых в этот момент номеров. Три заранее открытых дескриптора: стандартный ввод (), стандартный вывод (1) и стандартный вывод ошибок (2) процессу выдаются при запуске.

Механизм копирования окружения , описанный в лекции , подразумевает, в числе прочего, копирование всех открытых дескрипторов родительского процесса дочернему. В результате, и родительский, и дочерний процесс имеют под одинаковыми дескрипторами одни и те же потоки данных. Когда запускается стартовый командный интерпретатор , все три заранее открытых дескриптора связаны у него с терминалом (точнее, с соответствующим файлом-дыркой типа tty): пользователь вводит команды с клавиатуры и видит сообщения на экране. Следовательно, любая команда, запускаемая из командной оболочки, будет выводить на тот же терминал, а любая команда, запущенная интерактивно (не в фоне) - вводить оттуда.

Стандартный вывод

Мефодий уже сталкивался с тем, что некоторые программы умеют выводить не только на терминал, но и в файл, например, info при указании параметрического ключа « -o » с именем файла выведет текст руководства в файл, вместо того, чтобы отображать его на мониторе. Даже если разработчиками программы не предусмотрен такой ключ, Мефодию известен и другой способ сохранить вывод программы в файле вместо того, чтобы выводить его на монитор: поставить знак « > » и указать после него имя файла. Таким образом Мефодий уже создавал короткие текстовые файлы (сценарии) при помощи утилиты cat (см. лекцию Доступ процессов к файлам и каталогам).

$ cat > textfile Это файл для примеров. ^D $ ls -l textfile -rw-r--r-- 1 methody methody 23 Ноя 15 16:06 textfile

Пример 2 . Перенаправление стандартного вывода в файл

От использования символа « > » возможности самой утилиты cat , конечно, не расширились. Более того, cat в этом примере не получила от командной оболочки никаких параметров: ни знака « > », ни последующего имени файла. В этом случае cat работала как обычно, не зная (и даже не интересуясь!), куда попадут выведенные данные: на экран монитора, в файл или куда-нибудь ещё. Вместо того, чтобы самой обеспечивать доставку вывода до конечного адресата (будь то человек или файл), cat отправляет все данные на стандартный вывод (сокращённо - stdout).

Подмена стандартного вывода - задача командной оболочки (shell). В данном примере shell создаёт пустой файл, имя которого указано после знака « > », и дескриптор этого файла передаётся программе cat под номером 1 (стандартный вывод ). Делается это очень просто. В лекции Доступ процессов к файлам и каталогам было рассказано о том, как запускаются команды из оболочки. В частности, после выполнения fork() появляется два одинаковых процесса, один из которых - дочерний - должен запустить вместо себя команду (выполнить exec()). Так вот, перед этим он закрывает стандартный вывод (дескриптор 1 освобождается) и открывает файл (с ним связывается первый свободный дескриптор, т. е. 1), а запускаемой команде ничего знать и не надо: её стандартный вывод уже подменён. Эта операция называется перенаправлением стандартного вывода. В том случае, если файл уже существует, shell запишет его заново, полностью уничтожив всё, что в нём содержалось до этого. Поэтому Мефодию, чтобы продолжить записывать данные в textfile , потребуется другая операция - « >> ».

$ cat >> textfile Пример 1. ^D $ cat textfile Это файл для примеров. Пример 1. $

Пример 3 . Недеструктивное перенаправление стандартного вывода

Мефодий получил именно тот результат, который ему требовался: добавил в конец уже существующего файла данные со стандартного вывода очередной команды.

Стандартный вывод Поток данных, открываемый системой для каждого процесса в момент его запуска, и предназначенный для данных, выводимых процессом.

Стандартный ввод

Аналогичным образом для передачи данных на вход программе может быть использован стандартный ввод (сокращённо - stdin). При работе с командной строкой стандартный ввод - это символы, вводимые пользователем с клавиатуры. Стандартный ввод можно перенаправить при помощи командной оболочки, подав на него данные из некоторого файла. Символ « < » служит для перенаправления содержимого файла на стандартный ввод программе. Например, если вызвать утилиту sort без параметра, она будет читать строки со стандартного ввода. Команда « sort < имя_файла » подаст на ввод sort данные из файла.

$ sort < textfile Пример 1. Это файл для примеров. $

Пример 4 . Перенаправление стандартного ввода из файла

Результат действия этой команды совершенно аналогичен команде sort textfile , разница в том, что когда используется « < », sort получает данные со стандартного ввода, ничего не зная о файле « textfile », откуда они поступают. Механизм работы shell в данном случае тот же, что и при перенаправлении вывода: shell читает данные из файла « textfile », запускает утилиту sort и передаёт ей на стандартный ввод содержимое файла.

Стоит помнить, что операция « > » деструктивна : она всегда создаёт файл нулевой длины. Поэтому для, допустим, сортировки данных в файле надо применять последовательно sort < файл > новый_файл и mv новый_файл файл . Команда вида команда < файл > тот_же_файл просто урежет его до нулевой длины!

Стандартный ввод Поток данных, открываемый системой для каждого процесса в момент его запуска, и предназначенный для ввода данных.

Стандартный вывод ошибок

В качестве первого примера и упражнения на перенаправление Мефодий решил записать руководство по cat в свой файл cat.info:

$ info cat > cat.info info: Запись ноды (coreutils.info.bz2)cat invocation... info: Завершено. $ head -1 cat.info File: coreutils.info, Node: cat invocation, Next: tac invocation, Up: Output of entire files $

Пример 5 . Стандартный вывод ошибок

Удивлённый Мефодий обнаружил, что вопреки его указанию отправляться в файл две строки, выведенные командой info , всё равно проникли на терминал. Очевидно, эти строки не попали на стандартный вывод потому, что не относятся непосредственно к руководству, которое должна вывести программа, они информируют пользователя о ходе выполнения работы: записи руководства в файл. Для такого рода диагностических сообщений , а также для сообщений об ошибках, возникших в ходе выполнения программы, в Linux предусмотрен стандартный вывод ошибок (сокращённо - stderr).

Стандартный вывод ошибок Поток данных, открываемый системой для каждого процесса в момент его запуска, и предназначенный для диагностических сообщений , выводимых процессом.

Использование стандартного вывода ошибок наряду со стандартным выводом позволяет отделить собственно результат работы программы от разнообразной сопровождающей информации, например, направив их в разные файлы. Стандартный вывод ошибок может быть перенаправлен так же, как и стандартный ввод/вывод, для этого используется комбинация символов « 2 ».

$ info cat > cat.info 2> cat.stderr $ cat cat.stderr info: Запись ноды (coreutils.info.bz2)cat invocation... info: Завершено. $

Пример 6 . Перенаправление стандартного вывода ошибок

В этот раз на терминал уже ничего не попало, стандартный вывод отправился в файл cat.info , стандартный вывод ошибок - в cat.stderr . Вместо « > » и « 2 » Мефодий мог бы написать « 1> » и « 2> ». Цифры в данном случае обозначают номера дескрипторов открываемых файлов. Если некая утилита ожидает получить открытый дескриптор с номером, допустим, 4 , то чтобы её запустить обязательно потребуется использовать сочетание « 4> ».

Иногда, однако, требуется объединить стандартный вывод и страндартный вывод ошибок в одном файле, а не разделять их. В командной оболочке bash для этого имеется специальная последовательность « 2>&1 ». Это означает «направить стандартный вывод ошибок туда же, куда и стандартный вывод»:

$ info cat > cat.info 2>&1 $ head -3 cat.info info: Запись ноды (coreutils.info.bz2)cat invocation... info: Завершено. File: coreutils.info, Node: cat invocation, Next: tac invocation, Up: Output of entire files $

Пример 7 . Объединение стандартного вывода и стандартного вывода ошибок

В этом примере важен порядок перенаправлений: в командной строке Мефодий сначала указал, куда перенаправить стандартный вывод (« > cat.info ») и только потом велел направить туда же стандартный вывод ошибок. Сделай он наоборот (« 2>&1 > cat.info »), результат получился бы неожиданный: в файл попал бы только стандартный вывод, а диагностические сообщения появились бы на терминале. Однако логика здесь железная: на момент выполнения операции « 2>&1 » стандартный вывод был связан с терминалом, значит, после её выполнения стандартный вывод ошибок тоже будет связан с терминалом. А последующее перенаправление стандартного вывода в файл, конечно, никак не отразится на стандартном выводе ошибок. Номер в конструкции « &номер » - это номер открытого дескриптора. Если бы упомянутая выше утилита, записывающая в четвёртый дескриптор, была написана на shell, в ней бы использовались перенаправления вида « >&4 ». Чтобы не набирать громоздкую конструкцию « > файл 2>&1 » в bash используются сокращения: « &> файл » или, что то же самое, « >& файл ».

Перенаправление в никуда

Иногда заведомо известно, что какие-то данные, выведенные программой, не понадобятся. Например, предупреждения со стандартного вывода ошибок. В этом случае можно перенаправить стандартный вывод ошибок в файл-дырку , специально предназначенный для уничтожения данных - /dev/null . Всё, что записывается в этот файл, просто будет выброшено и нигде не сохранится .

$ info cat > cat.info 2> /dev/null $

Пример 8 . Перенаправление в /dev/null

Точно таким же образом можно избавиться и от стандартного вывода, отправив его в /dev/null .

Встроенные возможности перенаправления в Linux предоставляют вам широкий набор инструментов, используемых упрощения для всех видов задач. Умение управлять различными потоками ввода-вывода в значительно увеличит производительность, как при разработке сложного программного обеспечения, так и при управлении файлами с помощью командной строки.

Потоки ввода-вывода

Ввод и вывод в окружении Linux распределяется между тремя потоками:

  • Стандартный ввод (standard input, stdin, поток номер 0)
  • Стандартный вывод (standard output, stdout, номер 1)
  • Стандартная ошибка, или поток диагностики (standard error, stderr, номер 2)

При взаимодействии пользователя с терминалом стандартный ввод передается через клавиатуру пользователя. Стандартный вывод и стандартная ошибка отображаются на терминале пользователя в виде текста. Все эти три потока называются стандартными потоками.

Стандартный ввод

Стандартный входной поток обычно передаёт данные от пользователя к программе. Программы, которые предполагают стандартный ввод, обычно получают входные данные от устройства (например, клавиатуры). Стандартный ввод прекращается по достижении EOF (end-of-file, конец файла). EOF указывает на то, что больше данных для чтения нет.

Чтобы увидеть, как работает стандартный ввод, запустите программу cat. Название этого инструмента означает «concatenate» (связать или объединить что-либо). Обычно этот инструмент используется для объединения содержимого двух файлов. При запуске без аргументов cat открывает командную строку и принимает содержание стандартного ввода.

Теперь введите несколько цифр:

1
2
3
ctrl-d

Вводя цифру и нажимая enter, вы отправляете стандартный ввод запущенной программе cat, которая принимает эти данные. В свою очередь, программа cat отображает полученный ввод в стандартном выводе.

Пользователь может задать EOF, нажав ctrl-d, после чего программа cat остановится.

Стандартный вывод

Стандартный вывод записывает данные, сгенерированные программой. Если стандартный выходной поток не был перенаправлен, он выведет текст в терминал. Попробуйте запустить следующую команду для примера:

echo Sent to the terminal through standard output

Команда echo без дополнительных опций отображает на экране все аргументы, переданные ей в командной строке.

Теперь запустите echo без аргументов:

Команда вернёт пустую строку.

Стандартная ошибка

Этот стандартный поток записывает ошибки, создаваемые программой, которая вышла из строя. Как и стандартный вывод, этот поток отправляет данные в терминал.

Рассмотрим пример потока ошибок команды ls. Команда ls отображает содержимое каталогов.

Без аргументов эта команда возвращает содержимое текущего каталога. Если указать в качестве аргумента ls имя каталога, команда вернёт его содержимое.

Поскольку каталога % не существует, команда вернёт стандартную ошибку:

ls: cannot access %: No such file or directory

Перенаправление потоков

Linux предоставляет специальные команды для перенаправления каждого потока. Эти команды записывают стандартный вывод в файл. Если вывод перенаправлен в несуществующий файл, команда создаст новый файл с таким именем и сохранит в него перенаправленный вывод.

Команды с одной угловой скобкой переписывают существующий контент целевого файла:

  • > — стандартный вывод
  • < — стандартный ввод
  • 2> — стандартная ошибка

Команды с двойными угловыми скобками не переписывают содержимое целевого файла:

  • >> — стандартный вывод
  • << — стандартный ввод
  • 2>> — стандартная ошибка

Рассмотрим следующий пример:

cat > write_to_me.txt
a
b
c
ctrl-d

В данном примере команда cat используется для записи выходных данных в файл.

Просмотрите содержимое write_to_me.txt:

cat write_to_me.txt

Команда должна вернуть:

Снова перенаправьте cat в файл write_to_me.txt и введите три цифры.

cat > write_to_me.txt
1
2
3
ctrl-d

Теперь проверьте содержимое файла.

cat write_to_me.txt

Команда должна вернуть:

Как видите, файл содержит только последние выходные данные, поскольку в команде, перенаправляющей выход, использовалась одна угловая скобка.

Теперь попробуйте запустить ту же команду с двумя угловыми скобками:

cat >> write_to_me.txt
a
b
c
ctrl-d

Откройте write_to_me.txt:

1
2
3
a
b
c

Команды с двойными угловыми скобками не перезаписывают существующий контент, а дополняют его.

Конвейеры

Конвейеры (pipes) перенаправляют потоки вывода одной команды на вход другой. При этом данные, передаваемые второй программе, не отображаются в терминале. На экране данные появятся только после обработки второй программой.

Конвейеры в Linux представлены вертикальной чертой.

Например:

Такая команда передаст вывод ls (содержимое текущего каталога) программе less, которая отображает передаваемые ей данные построчно. Как правило, ls выводит содержимое каталогов подряд, не разбивая на строки. Если перенаправить вывод ls в less, то последняя команда разделит вывод на строки.

Как видите, конвейер может перенаправить вывод одной команды на вход другой, в отличие от > и >>, которые перенаправляют данные только в файлы.

Фильтры

Фильтры – это команды, которые могут изменить перенаправление и вывод конвейера.

Примечание : Фильтры также являются стандартными командами Linux, которые можно использовать и без конвейера.

  • find – выполняет поиск файла по имени.
  • grep – выполняет поиск текста по заданному шаблону.
  • tee – перенаправляет стандартный ввод в стандартный вывод и один или несколько файлов.
  • tr – поиск и замена строк.
  • wc – подсчёт символов, строк и слов.

Примеры перенаправления ввода-вывода

Теперь, когда вы ознакомились с основными понятиями и механизмами перенаправления, рассмотрим несколько базовых примеров их использования.

команда > файл

Такой шаблон перенаправляет стандартный вывод команды в файл.

ls ~ > root_dir_contents.txt

Эта команда передает содержимое root каталога системы в качестве стандартного вывода и записывает вывод в файл root_dir_contents. Это удалит все предыдущее содержимое в файле, так как в команде использована одна угловая скобка.

команда > /dev/null

/dev/null – это специальный файл (так называемое «пустое устройство»), который используется для подавления стандартного потока вывода или диагностики, чтобы избежать нежелательного вывода в консоль. Все данные, попадающие в /dev/null, сбрасываются. Перенаправление в /dev/null обычно используется в сценариях оболочки.

ls > /dev/null

Такая команда сбрасывает стандартный выходной поток, возвращаемый командой ls, передав его в /dev/null.

команда 2 > файл

Этот шаблон перенаправляет стандартный поток ошибок команды в файл, перезаписывая его текущее содержимое.

mkdir "" 2> mkdir_log.txt

Эта команда перенаправит ошибку, вызванную неверным именем каталога, и запишет её в log.txt. Обратите внимание: ошибка по-прежнему отображается в терминале.

команда >> файл

Этот шаблон перенаправляет стандартный выход команды в файл, не переписывая текущего содержимого файла.

echo Written to a new file > data.txt
echo Appended to an existing file"s contents >> data.txt

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

команда 2>>файл

Этот шаблон перенаправляет стандартный поток ошибок команды в файл, не перезаписывая существующего содержимого файла. Он подходит для создания логов ошибок программы или сервиса, поскольку содержимое лога не будет постоянно обновляться.

find "" 2> stderr_log.txt
wc "" 2>> stderr_log.txt

Приведенная выше команда перенаправляет сообщение об ошибке, вызванное неверным аргументом find, в файл stderr_log.txt, а затем добавляет в него сообщение об ошибке, вызванной недействительным аргументом wc.

команда | команда

Этот шаблон перенаправляет стандартный выход первой команды на стандартный вход второй команды.

find /var lib | grep deb

Эта команда ищет в каталоге /var и его подкаталогах имена файлов и расширения deb и возвращает пути к файлам, выделяя шаблон поиска красным цветом.

команда | tee файл

Такой шаблон перенаправляет стандартный вывод команды в файл и переписывает его содержимое, а затем отображает перенаправленный выход в терминале. Если указанного файла не существует, он создает новый файл.

В данном шаблоне команда tee, как правило, используется для просмотра вывода программы и одновременного сохранения его в файл.

wc /etc/magic | tee magic_count.txt

Такая команда передаёт количество символов, строк и слов в файле magic (Linux использует его для определения типов файлов) команде tee, которая отправляет эти данные в терминал и в файл magic_count.txt.

команда | команда | команда >> файл

Этот шаблон перенаправляет стандартный вывод первой команды и фильтрует ее через следующие две команды, а затем добавляет окончательный результат в файл.

ls ~ | grep *tar | tr e E >> ls_log.txt

Такая команда отправляет вывод ls для каталога root команде grep. В свою очередь, grep ищет в полученных данных файлы tar. После этого результат grep передаётся команде tr, которая заменит все символы е символом Е. Полученный результат будет добавлен в файл ls_log.txt (если такого файла не существует, команда создаст его автоматически).

Заключение

Функции перенаправления ввода-вывода в Linux сначала кажутся слишком сложными. Однако работа с перенаправлением – один из важнейших навыков системного администратора.

Чтобы узнать больше о какой-либо команде, используйте:

man command | less

Например:

Такая команда вернёт полный список команд для tee.

Tags:

Рекомендуем почитать

Наверх