Перенаправление вывода linux bash

Глава 16. Перенаправление ввода/вывода

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

С каждым открытым файлом связан дескриптор файла. [1] Дескрипторы файлов stdin, stdout и stderr — 0, 1 и 2, соответственно. При открытии дополнительных файлов, дескрипторы с 3 по 9 остаются незанятыми. Иногда дополнительные дескрипторы могут сослужить неплохую службу, временно сохраняя в себе ссылку на stdin, stdout или stderr. [2] Это упрощает возврат дескрипторов в нормальное состояние после сложных манипуляций с перенаправлением и перестановками (см. Пример 16-1).

Операции перенаправления и/или конвейеры могут комбинироваться в одной командной строке.

Допускается перенаправление нескольких потоков в один файл.

Закрытие дескрипторов файлов

Закрыть дескриптор входного файла n.

Закрыть дескриптор выходного файла n.

Дочерние процессы наследуют дескрипторы открытых файлов. По этой причине и работают конвейеры. Чтобы предотвратить наследование дескрипторов — закройте их перед запуском дочернего процесса.

Дополнительные сведения о перенаправлении ввода/вывода вы найдете в Приложение D.

16.1. С помощью команды exec

Команда exec stdin на файл. С этого момента весь ввод, вместо stdin (обычно это клавиатура), будет производиться из этого файла. Это дает возможность читать содержимое файла, строку за строкой, и анализировать каждую введенную строку с помощью sed и/или awk.

Пример 16-1. Перенаправление stdin с помощью exec

Аналогично, конструкция exec >filename перенаправляет вывод на stdout в заданный файл. После этого, весь вывод от команд, который обычно направляется на stdout, теперь выводится в этот файл.

Пример 16-2. Перенаправление stdout с помощью exec

Пример 16-3. Одновременное перенаправление устройств, stdin и stdout, с помощью команды exec

Примечания

дескриптор файла — это просто число, по которому система идентифицирует открытые файлы. Рассматривайте его как упрощенную версию указателя на файл.

При использрвании дескриптора с номером 5 могут возникать проблемы. Когда Bash порождает дочерний процесс, например командой exec, то дочерний процесс наследует дескриптор 5 как «открытый» (см. архив почты Чета Рамея (Chet Ramey), SUBJECT: RE: File descriptor 5 is held open) Поэтому, лучше не использовать этот дескриптор.

Источник

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

В Bash реализована возможность перенаправления потоков ввода и вывода. Что это значит?

В стандартный поток ввода поступают данные, которые вводятся с клавиатуры. Стандартным потоком вывода является экран монитора. Другими словами, в командную строку Bash’а поступают данные, вводимые с клавиатуры. Если команда предполагает текстовый вывод, Bash выводит данные на экран.

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

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

Читайте также:  Oracle sql developer ��� linux

В Bash знак больше «>» обозначает перенаправление стандартного потока вывода. В данном случае в файл. То есть cat по-умолчанию выводит данные на экран, но поскольку они были перенаправлены, то данные на экран выводиться не будут. На экране видны только вводимые строки, выводимые оказываются в файле.

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

Два знака больше «>>» – это тоже перенаправление вывода, но такое, когда данные добавляются в конец объекта (в данном случае файла), если он существует. Используй мы только один знак больше, файл был бы перезаписан.

На скрине выше командой cat note.txt файл читается. Так устроена команда cat, что если ей передается аргумент, то она не будет работать в интерактивном режиме, а возьмет данные из указанного файла и выведет их на экран. Поэтому это равносильно cat , где знак меньше «

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

Можно было бы ожидать, что если команде ls, которая выводит содержимое каталога, передать файл, содержащий адрес каталога, то она выведет объекты этого каталога. Однако это не так.

Такое перенаправление не работает. А там где «работает» можно обойтись и без него, то есть команда сама «знает», что если передается имя файла, или она употребима только с именем файла, то данные надо брать из него.

Здесь команда grep ищет первый аргумент во втором. Если находит, возвращает строку с ним. Программа wc считает количество строк, слов и символов в файле. С помощью sort строки сортируются.

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

С другой стороны, выводы в файл команд ls и других работают.

В Unix-подобных операционных системах перенаправлять получение/передачу данных можно не только со стандартных ввода-вывода на файл. Данные могут поступать из, так называемого, программного канала. Равно и выводиться в него.

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

Программные каналы позволяют избежать излишнего создания файлов с промежуточными данными. Рассмотрим пример. Команда wc считает количество строк, слов и символов в файле. С ключом -l – только количество слов. Пусть нам надо узнать общее количество файлов, содержащихся в каталоге.

В случае перенаправления ввода-вывода в файл, потребовалось бы сначала направить вывод программы ls в файл, после чего передать его программе wc. При этом был посчитан и этот файл (если он был сохранен в каталоге, который анализируется).

В случае же программного конвейера между ls и wc создается канал. В результате данные, отправляемые ls на стандартный вывод, то есть монитор, оболочка Bash «перехватывает» и отправляет в канал, из которого данные передаются оболочкой на ввод wc.

Читайте также:  Тонкий клиент rdp windows

Имя команды cat – это сокращение от «catenate» (связывать, соединять). Если в качестве аргументов программе передать несколько файлов, то их содержимое будет соединено и выведено на экран.

Создайте два текстовых файла с какими-либо данными. С помощью программы cat объедините данные этих файлов в третьем файле.

Курс с ответами к заданиям и дополнительными уроками:
android-приложение, pdf-версия.

Источник

Вывод в файл Bash в Linux

Часто возникает необходимость, чтобы скрипт командного интерпретатора Bash выводил результат своей работы. По умолчанию он отображает стандартный поток данных — окно терминала. Это удобно для обработки результатов небольшого объёма или, чтобы сразу увидеть необходимые данные.

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

Стандартные дескрипторы вывода

В системе GNU/Linux каждый объект является файлом. Это правило работает также для процессов ввода/вывода. Каждый файловый объект в системе обозначается дескриптором файла — неотрицательным числом, однозначно определяющим открытые в сеансе файлы. Один процесс может открыть до девяти дескрипторов.

В командном интерпретаторе Bash первые три дескриптора зарезервированы для специального назначения:

Дескриптор Сокращение Название
0 STDIN Стандартный ввод
1 STDOUT Стандартный вывод
2 STDERR Стандартный вывод ошибок

Их предназначение — обработка ввода/вывода в сценариях. По умолчанию стандартным потоком ввода является клавиатура, а вывода — терминал. Рассмотрим подробно последний.

Вывод в файл Bash

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

Для того, чтобы перенаправить поток вывода с терминала в файл, используется знак «больше» (>).

#!/bin/bash
echo «Строка 1»
echo «Промежуточная строка» > file
echo «Строка 2» > file

Как результат, «Строка 1» выводится в терминале, а в файл file записывается только «Строка 2»:

Связано это с тем, что > перезаписывает файл новыми данными. Для того, чтобы дописать информацию в конец файла, используется два знака «больше» (>>).

#!/bin/bash
echo «Строка 1»
echo «Промежуточная строка» > file
echo «Строка 2» >> file

Здесь «Промежуточная строка» перезаписала предыдущее содержание file, а «Строка 2» дописалась в его конец.

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

#!/bin/bash
ls badfile > file2
echo «Строка 2» >> file2

В данном случае ошибка была в том, что команда ls не смогла найти файл badfile, о чём Bash и сообщил. Но вывелось сообщение в терминал, а не записалось в файл. Всё потому, что использование перенаправления потоков указывает интерпретатору отделять мух от котлет ошибки от основной информации.

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

2. Перенаправление потока ошибок

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

По умолчанию STDERR указывает в то же место, что и STDOUT, хотя для них и предназначены разные дескрипторы. Но, как было показано в примере, использование перенаправления заставляет Bash разделить эти потоки.

Чтобы выполнить перенаправление вывода в файл Linux для ошибок, следует перед знаком«больше» указать дескриптор 2.

#!/bin/bash
ls badfile 2> errors
echo «Строка 1» > file3
echo «Строка 2» >> file3

В результате работы скрипта создан файл errors, в который записана ошибка выполнения команды ls, а в file3 записаны предназначенные строки. Таким образом, выполнение сценария не сопровождается выводом информации в терминал.

Пример того, как одна команда возвращает и положительный результат, и ошибку:

ls -lh test badtest 2> errors

Команда ls попыталась показать наличие файлов test и badtest. Первый присутствовал в текущем каталоге, а второй — нет. Но сообщение об ошибке было записано в отдельный файл.

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

ls -lh test test2 badtest 2> errors 1> output

Результат успешного выполнения записан в файл output, а сообщение об ошибке — в errors.

По желанию можно выводить и ошибки, и обычные данные в один файл, используя &>.

ls -lh test badtest &> output

Обратите внимание, что Bash присваивает сообщениям об ошибке более высокий приоритет по сравнению с данными, поэтому в случае общего перенаправления ошибки всегда будут располагаться в начале.

Временные перенаправления в скриптах

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

#!/bin/bash
echo «Это сообщение об ошибке» >&2
echo «Это нормальное сообщение»

При выполнении программы обычно нельзя будет обнаружить отличия:

Вспомним, что GNU/Linux по умолчанию направляет вывод STDERR в STDOUT. Но если при выполнении скрипта будет перенаправлен поток ошибок, то Bash, как и полагается, разделит вывод.

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

Постоянные перенаправления в скриптах

Если в сценарии необходимо перенаправить вывод в файл Linux для большого объёма данных, то указание способа вывода в каждой инструкции echo будет неудобным и трудоёмким занятием. Вместо этого можно указать, что в ходе выполнения данного скрипта должно осуществляться перенаправление конкретного дескриптора с помощью команды exec:

#!/bin/bash
exec 1> testout
echo «Это тест перенаправления всего вывода»
echo «из скрипта в другой файл»
echo «без использования временного перенаправления»

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

Также существует возможность перенаправлять вывод (в том числе и ошибок) в произвольном участке сценария:

#!/bin/bash
exec 2> testerror
echo «Это начально скрипта»
echo «И это первые две строки»
exec 1> testout
echo «Вывод сценария перенаправлен»
echo «из с терминала в другой файл»
echo «но эта строка записана в файл ошибок» >&2

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

Выводы

Перенаправление в скриптах Bash, чтобы выполнить вывод в файл Bash, является хорошим средством ведения различных журналов, особенно в фоновом режиме.

Использование временного и постоянного перенаправлений в сценариях позволяет создавать собственные сообщения об ошибках для записи в отличное от STDOUT место.

Источник

Читайте также:  Компьютер виснет при перезагрузке windows
Оцените статью