Главная >> Инструкции >> Вывод в файл Bash в Linux

Вывод в файл 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 место.

Реклама
Посмотреть детали

Proton Drive — это облачное хранилище со сквозным шифрованием от компании, которая создала Proton Mail, которое может стать хорошей заменой Google Диску. Все файлы шифруются на вашем устройстве, поэтому они недоступны даже для самой компании Proton. Вы получаете синхронизацию между устройствами, общий доступ к файлам, автоматическое резервное копирование фото и удобные приложения для всех платформ, но с гарантией, что ваши данные останутся исключительно вашими и никто не будет тренировать на них AI. В бесплатной версии доступно 5 ГБ места на диске. Посмотреть детали

2 комментария к “Вывод в файл Bash в Linux”

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

    Ответить

Оставьте комментарий