- Перенаправление ввода и вывода
- Стандартный вывод
- Стандартный ввод
- Стандартный вывод ошибок
- Перенаправление в никуда
- Перенаправление ввода/вывода в Linux
- Введение
- Требования
- Потоки
- Стандартный ввод
- Пример
- Стандартный вывод
- Пример
- Стандартная ошибка
- Пример
- Перенаправление потока
- Пример
- Каналы
- Пример
- Пример
- Фильтры
- Пример
- Пример
- Заключение
Перенаправление ввода и вывода
Для того, чтобы записать данные в файл или прочитать их оттуда, процессу необходимо сначала открыть этот файл (при открытии на запись, возможно, придётся предварительно создать его). При этом процесс получает дескриптор (описатель) открытого файла — уникальное для этого процесса число, которое он и будет использовать во всех операциях записи. Первый открытый файл получит дескриптор 0 , второй — 1 и так далее. Закончив работу с файлом, процесс закрывает его, при этом дескриптор освобождается и может быть использован повторно. Если процесс завершается, не закрыв файлы, за него это делает система. Строго говоря, только в операции открытия дескриптора указывается, какой именно файл будет использоваться. В качестве «файла» используются и обычные файлы, и файлы-дырки (чаще всего — терминалы), и каналы, описанные в разделе Pipeline..Конвейер. Дальнейшие операции — чтение, запись и закрытие, работают с дескриптором, как с потоком данных, а куда именно ведёт этот поток, неважно.
Каждый процесс Linux получает при старте три «файла», открытых для него системой. Первый из них (дескриптор 0 ) открыт на чтение, это стандартный ввод процесса. Именно со стандартным вводом работают все операции чтения, если в них не указан дескриптор файла. Второй (дескриптор 1 ) — открыт на запись , это стандартный вывод процесса. С ним работают все операции записи, если дескриптор файла не указан в них явно. Наконец, третий поток данных (дескриптор 2 ) предназначается для вывода диагностических сообщений, он называется стандартный вывод ошибок. Поскольку эти три дескриптора уже открыты к моменту запуска процесса, первый файл, открытый самим процессом, будет, скорее всего, иметь дескриптор 3 .
дескриптор Описатель потока данных, открытого процессом. Дескрипторы нумеруются начиная с 0 . При открытии нового потока данных его дескриптор получает наименьший из неиспользуемых в этот момент номеров. Три заранее открытых дескриптора: стандартный ввод ( 0 ), стандартный вывод ( 1 ) и стандартный вывод ошибок ( 2 ) процессу выдаются при запуске.
Механизм копирования окружения, описанный в лекции Доступ процессов к файлам и каталогам, подразумевает, в числе прочего, копирование всех открытых дескрипторов родительского процесса дочернему. В результате, и родительский, и дочерний процесс имеют под одинаковыми дескрипторами одни и те же потоки данных. Когда запускается стартовый командный интерпретатор, все три заранее открытых дескриптора связаны у него с терминалом (точнее, с соответствующим файлом-дыркой типа tty ): пользователь вводит команды с клавиатуры и видит сообщения на экране. Следовательно, любая команда, запускаемая из командной оболочки, будет выводить на тот же терминал, а любая команда, запущенная интерактивно (не в фоне) — вводить оттуда.
Стандартный вывод
Мефодий уже сталкивался с тем, что некоторые программы умеют выводить не только на терминал, но и в файл, например, info при указании параметрического ключа « -o » с именем файла выведет текст руководства в файл, вместо того, чтобы отображать его на мониторе. Даже если разработчиками программы не предусмотрен такой ключ, Мефодию известен и другой способ сохранить вывод программы в файле вместо того, чтобы выводить его на монитор: поставить знак « > » и указать после него имя файла. Таким образом Мефодий уже создавал короткие текстовые файлы (сценарии) при помощи утилиты cat (см. лекцию Доступ процессов к файлам и каталогам).
[methody@localhost methody]$ cat > textfile
Это файл для примеров.
^D
[methody@localhost methody]$ 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 , потребуется другая операция — « >> ».
[methody@localhost methody]$ cat >> textfile
Пример 1.
^D
[methody@localhost methody]$ cat textfile
Это файл для примеров.
Пример 1.
[methody@localhost methody]$
Пример 3. Недеструктивное перенаправление стандартного вывода
Мефодий получил именно тот результат, который ему требовался: добавил в конец уже существующего файла данные со стандартного вывода очередной команды.
стандартный вывод Поток данных, открываемый системой для каждого процесса в момент его запуска, и предназначенный для данных, выводимых процессом.
Стандартный ввод
Аналогичным образом для передачи данных на вход программе может быть использован стандартный ввод (сокращённо — stdin). При работе с командной строкой стандартный ввод — это символы, вводимые пользователем с клавиатуры. Стандартный ввод можно перенаправить при помощи командной оболочки, подав на него данные из некоторого файла. Символ « » служит для перенаправления содержимого файла на стандартный ввод программе. Например, если вызвать утилиту sort без параметра, она будет читать строки со стандартного ввода. Команда « sort » подаст на ввод sort данные из файла.
[methody@localhost methody]$ sort
Пример 4. Перенаправление стандартного ввода из файла
Результат действия этой команды совершенно аналогичен команде sort textfile , разница в том, что когда используется « », sort получает данные со стандартного ввода, ничего не зная о файле « textfile », откуда они поступают. Механизм работы shell в данном случае тот же, что и при перенаправлении вывода: shell читает данные из файла « textfile », запускает утилиту sort и передаёт ей на стандартный ввод содержимое файла.
Стоит помнить, что операция « > » деструктивна: она всегда создаёт файл нулевой длины. Поэтому для, допустим, сортировки данных в файле надо применять последовательно sort новый_файл и mv новый_файл файл . Команда вида команда тот_же_файл просто урежет его до нулевой длины!
стандартный ввод Поток данных, открываемый системой для каждого процесса в момент его запуска, и предназначенный для ввода данных.
Стандартный вывод ошибок
В качестве первого примера и упражнения на перенаправление Мефодий решил записать руководство по cat в свой файл cat.info :
[methody@localhost methody]$ info cat > cat.info
info: Запись ноды (coreutils.info.bz2)cat invocation.
info: Завершено.
[methody@localhost methody]$ head -1 cat.info
File: coreutils.info, Node: cat invocation, Next: tac invocation, Up: Output of entire files
[methody@localhost methody]$
Пример 5. Стандартный вывод ошибок
Удивлённый Мефодий обнаружил, что вопреки его указанию отправляться в файл две строки, выведенные командой info , всё равно проникли на терминал. Очевидно, эти строки не попали на стандартный вывод потому, что не относятся непосредственно к руководству, которое должна вывести программа, они информируют пользователя о ходе выполнения работы: записи руководства в файл. Для такого рода диагностических сообщений, а также для сообщений об ошибках, возникших в ходе выполнения программы, в Linux предусмотрен стандартный вывод ошибок (сокращённо — stderr).
стандартный вывод ошибок Поток данных, открываемый системой для каждого процесса в момент его запуска, и предназначенный для диагностических сообщений, выводимых процессом.
Использование стандартного вывода ошибок наряду со стандартным выводом позволяет отделить собственно результат работы программы от разнообразной сопровождающей информации, например, направив их в разные файлы. Стандартный вывод ошибок может быть перенаправлен так же, как и стандартный ввод/вывод, для этого используется комбинация символов « 2 ».
[methody@localhost methody]$ info cat > cat.info 2> cat.stderr
[methody@localhost methody]$ cat cat.stderr
info: Запись ноды (coreutils.info.bz2)cat invocation.
info: Завершено.
[methody@localhost methody]$
Пример 6. Перенаправление стандартного вывода ошибок
В этот раз на терминал уже ничего не попало, стандартный вывод отправился в файл cat.info , стандартный вывод ошибок — в cat.stderr . Вместо « > » и « 2 » Мефодий мог бы написать « 1> » и « 2> ». Цифры в данном случае обозначают номера дескрипторов открываемых файлов. Если некая утилита ожидает получить открытый дескриптор с номером, допустим, 4 , то чтобы её запустить обязательно потребуется использовать сочетание « 4> ».
Иногда, однако, требуется объединить стандартный вывод и страндартный вывод ошибок в одном файле, а не разделять их. В командной оболочке bash для этого имеется специальная последовательность « 2>&1 ». Это означает «направить стандартный вывод ошибок туда же, куда и стандартный вывод»:
[methody@localhost methody]$ info cat > cat.info 2>&1
[methody@localhost methody]$ 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
[methody@localhost methody]$
Пример 7. Объединение стандартного вывода и стандартного вывода ошибок
В этом примере важен порядок перенаправлений: в командной строке Мефодий сначала указал, куда перенаправить стандартный вывод (« > cat.info ») и только потом велел направить туда же стандартный вывод ошибок. Сделай он наоборот (« 2>&1 > cat.info »), результат получился бы неожиданный: в файл попал бы только стандартный вывод, а диагностические сообщения появились бы на терминале. Однако логика здесь железная: на момент выполнения операции « 2>&1 » стандартный вывод был связан с терминалом, значит, после её выполнения стандартный вывод ошибок тоже будет связан с терминалом. А последующее перенаправление стандартного вывода в файл, конечно, никак не отразится на стандартном выводе ошибок. Номер в конструкции « &номер » — это номер открытого дескриптора. Если бы упомянутая выше утилита, записывающая в четвёртый дескриптор, была написана на shell, в ней бы использовались перенаправления вида « >&4 ». Чтобы не набирать громоздкую конструкцию « > файл 2>&1 » в bash используются сокращения: « &> файл » или, что то же самое, « >& файл ».
Перенаправление в никуда
Иногда заведомо известно, что какие-то данные, выведенные программой, не понадобятся. Например, предупреждения со стандартного вывода ошибок. В этом случае можно перенаправить стандартный вывод ошибок в файл-дырку, специально предназначенный для уничтожения данных — /dev/null . Всё, что записывается в этот файл, просто будет выброшено и нигде не сохранится.
[methody@localhost methody]$ info cat > cat.info 2> /dev/null
[methody@localhost methody]$
Пример 8. Перенаправление в /dev/null
Точно таким же образом можно избавиться и от стандартного вывода, отправив его в /dev/null .
Источник
Перенаправление ввода/вывода в Linux
Введение
Стандартные потоки ввода и вывода в Linux являются одним из наиболее распространенных средств для обмена информацией процессов, а перенаправление >, >> и | является одной из самых популярных конструкций командного интерпретатора.
В данной статье мы ознакомимся с возможностями перенаправления потоков ввода/вывода, используемых при работе файлами и командами.
Требования
- Linux-система, например, Ubuntu 20.04
Потоки
Стандартный ввод при работе пользователя в терминале передается через клавиатуру.
Стандартный вывод и стандартная ошибка отображаются на дисплее терминала пользователя в виде текста.
Ввод и вывод распределяется между тремя стандартными потоками:
- stdin — стандартный ввод (клавиатура),
- stdout — стандартный вывод (экран),
- stderr — стандартная ошибка (вывод ошибок на экран).
Потоки также пронумерованы:
Из стандартного ввода команда может только считывать данные, а два других потока могут использоваться только для записи. Данные выводятся на экран и считываются с клавиатуры, так как стандартные потоки по умолчанию ассоциированы с терминалом пользователя. Потоки можно подключать к чему угодно: к файлам, программам и даже устройствам. В командном интерпретаторе bash такая операция называется перенаправлением:
- file — направить стандартный поток вывода в файл. Если файл не существует, он будет создан, если существует — перезаписан сверху.
- 2> file — направить стандартный поток ошибок в файл. Если файл не существует, он будет создан, если существует — перезаписан сверху.
- >>file — направить стандартный поток вывода в файл. Если файл не существует, он будет создан, если существует — данные будут дописаны к нему в конец.
- 2>>file — направить стандартный поток ошибок в файл. Если файл не существует, он будет создан, если существует — данные будут дописаны к нему в конец.
- &>file или >&file — направить стандартный поток вывода и стандартный поток ошибок в файл. Другая форма записи: >file 2>&1.
Стандартный ввод
Стандартный входной поток обычно переносит данные от пользователя к программе. Программы, которые предполагают стандартный ввод, обычно получают входные данные от устройства типа клавиатура. Стандартный ввод прекращается по достижении EOF (конец файла), который указывает на то, что данных для чтения больше нет.
EOF вводится нажатием сочетания клавиш Ctrl+D.
Рассмотрим работу со стандартным выводом на примере команды cat (от CONCATENATE, в переводе «связать» или «объединить что-то»).
Cat обычно используется для объединения содержимого двух файлов.
Cat отправляет полученные входные данные на дисплей терминала в качестве стандартного вывода и останавливается после того как получает EOF.
Пример
В открывшейся строке введите, например, 1 и нажмите клавишу Enter. На дисплей выводится 1. Введите a и нажмите клавишу Enter. На дисплей выводится a.
Дисплей терминала выглядит следующим образом:
Для завершения ввода данных следует нажать сочетание клавиш Ctrl + D.
Стандартный вывод
Стандартный вывод записывает данные, сгенерированные программой. Когда стандартный выходной поток не перенаправляется в какой-либо файл, он выводит текст на дисплей терминала.
При использовании без каких-либо дополнительных опций, команда echo выводит на экран любой аргумент, который передается ему в командной строке:
Аргументом является то, что получено программой, в результате на дисплей терминала будет выведено:
При выполнении echo без каких-либо аргументов, возвращается пустая строка.
Пример
Команда объединяет три файла: file1, file2 и file3 в один файл bigfile:
Команда cat по очереди выводит содержимое файлов, перечисленных в качестве параметров на стандартный поток вывода. Стандартный поток вывода перенаправлен в файл bigfile.
Стандартная ошибка
Стандартная ошибка записывает ошибки, возникающие в ходе исполнения программы. Как и в случае стандартного вывода, по умолчанию этот поток выводится на терминал дисплея.
Пример
Рассмотрим пример стандартной ошибки с помощью команды ls, которая выводит список содержимого каталогов.
При запуске без аргументов ls выводит содержимое в пределах текущего каталога.
Введем команду ls с каталогом % в качестве аргумента:
В результате должно выводиться содержимое соответствующей папки. Но так как каталога % не существует, на дисплей терминала будет выведен следующий текст стандартной ошибки:
Перенаправление потока
Linux включает в себя команды перенаправления для каждого потока.
Команды со знаками > или — стандартный вывод,
Команды со знаками >> или > — стандартный вывод,
Пример
В приведенном примере команда cat используется для записи в файл file1, который создается в результате цикла:
Для завершения цикла нажмите сочетание клавиш Ctrl + D.
Если файла file1 не существует, то в текущем каталоге создается новый файл с таким именем.
Для просмотра содержимого файла file1 введите команду:
В результате на дисплей терминала должно быть выведено следующее:
Для перезаписи содержимого файла введите следующее:
Для завершения цикла нажмите сочетание клавиш Ctrl + D.
В результате на дисплей терминала должно быть выведено следующее:
Предыдущего текста в текущем файле больше не существует, так как содержимое файла было переписано командой >.
Для добавления нового текста к уже существующему в файле с помощью двойных скобок >> выполните команду:
Для завершения цикла нажмите сочетание клавиш Ctrl + D.
Откройте file1 снова и в результате на дисплее монитора должно быть отражено следующее:
Каналы
Каналы используются для перенаправления потока из одной программы в другую. Стандартный вывод данных после выполнения одной команды перенаправляется в другую через канал. Данные первой программы, которые получает вторая программа, не будут отображаться. На дисплей терминала будут выведены только отфильтрованные данные, возвращаемые второй командой.
Пример
В результате каждый файл текущего каталога будет размещен на новой строке:
Перенаправлять данные с помощью каналов можно как из одной команды в другую, так и из одного файла к другому, а перенаправление с помощью > и >> возможно только для перенаправления данных в файлах.
Пример
Для сохранения имен файлов, содержащих строку «LOG», используется следующая команда:
Вывод команды dir отсылается в команду-фильтр find. Имена файлов, содержащие строку «LOG», хранятся в файле loglist в виде списка (например, Config.log, Logdat.svd и Mylog.bat).
При использовании нескольких фильтров в одной команде рекомендуется разделять их с помощью знака канала |.
Фильтры
Фильтры представляют собой стандартные команды Linux, которые могут быть использованы без каналов:
- find — возвращает файлы с именами, которые соответствуют передаваемому аргументу.
- grep — возвращает только строки, содержащие (или не содержащие) заданное регулярное выражение.
- tee — перенаправляет стандартный ввод как стандартный вывод и один или несколько файлов.
- tr — находит и заменяет одну строку другой.
- wc — подсчитывает символы, линии и слова.
Как правило, все нижеприведенные команды работают как фильтры, если у них нет аргументов (опции могут быть):
- cat — считывает данные со стандартного потока ввода и передает их на стандартный поток вывода. Без опций работает как простой повторитель. С опциями может фильтровать пустые строки, нумеровать строки и делать другую подобную работу.
- head — показывает первые 10 строк (или другое заданное количество), считанных со стандартного потока ввода.
- tail — показывает последние 10 строк (или другое заданное количество), считанные со стандартного потока ввода. Важный частный случай tail -f, который в режиме слежения показывает концовку файла. Это используется, в частности, для просмотра файлов журнальных сообщений.
- cut — вырезает столбец (по символам или полям) из потока ввода и передает на поток вывода. В качестве разделителей полей могут использоваться любые символы.
- sort — сортирует данные в соответствии с какими-либо критериями, например, арифметически по второму столбцу.
- uniq — удаляет повторяющиеся строки. Или (с ключом -с) не просто удалить, а написать сколько таких строк было. Учитываются только подряд идущие одинаковые строки, поэтому часто данные сортируются перед тем как отправить их на вход программе.
- bc — вычисляет каждую отдельную строку потока и записывает вместо нее результат вычисления.
- hexdump — показывает шестнадцатеричное представление данных, поступающих на стандартный поток ввода.
- strings — выделяет и показывает в стандартном потоке (или файле) то, что напоминает строки. Всё что не похоже на строковые последовательности, игнорируется. Команда полезна в сочетании с grep для поиска интересующих строковых последовательностей в бинарных файлах.
- sed — обрабатывает текст в соответствии с заданным скриптом. Наиболее часто используется для замены текста в потоке: sed s/было/стало/g.
- awk — обрабатывает текст в соответствии с заданным скриптом. Как правило, используется для обработки текстовых таблиц, например, вывод ps aux и т.д.
- sh -s — текст, который передается на стандартный поток ввода sh -s. может интерпретироваться как последовательность команд shell. На выход передается результат их исполнения.
- ssh — средство удаленного доступа ssh, может работать как фильтр, который подхватывает данные, переданные ему на стандартный поток ввода, затем передает их на удаленный хост и подает на вход процессу программы, имя которой было передано ему в качестве аргумента. Результат выполнения программы (то есть то, что она выдала на стандартный поток вывода) передается со стандартного вывода ssh.
Если в качестве аргумента передается файл, команда-фильтр считывает данные из этого файла, а не со стандартного потока ввода (есть исключения, например, команда tr, обрабатывающая данные, поступающие исключительно через стандартный поток ввода).
Пример
Команда tee, как правило, используется для просмотра выводимого содержимого при одновременном сохранении его в файл.
Пример
Допускается перенаправление нескольких потоков в один файл:
В результате сообщение о неверной опции «z» в команде ls будет записано в файл t2, поскольку stderr перенаправлен в файл.
Для просмотра содержимого файла file3 введите команду cat:
В результате на дисплее терминала отобразиться следующее:
Заключение
Мы рассмотрели возможности работы с перенаправлениями потоков >, >> и |, использование которых позволяет лучше работать с bash-скриптами.
Источник