ЯдроКодаподготовка к экзаменам
Учебная платформа

Загружаем материалы

Подготавливаем материалы и навигацию по разделу.

Перенаправление и tee: сохраняем вывод без потери диагностики

Автор: · Обновлено

Перенаправление меняет, откуда процесс читает и куда пишет, ещё до его запуска. Оно позволяет сохранить отчёт, отделить диагностику, подать файл как stdin или одновременно видеть…

Перенаправление меняет, откуда процесс читает и куда пишет, ещё до его запуска. Оно позволяет сохранить отчёт, отделить диагностику, подать файл как stdin или одновременно видеть поток на экране и записывать его через tee.

Операторы чтения и записи

<input подключает файл к stdin, >output создаёт или обнуляет файл для stdout, а >>output добавляет данные в конец. Номер перед оператором выбирает дескриптор: 2>errors.log относится к stderr.

wc -l </etc/services
printf '%s\n' first >events.log
printf '%s\n' second >>events.log
ls /missing >listing.txt 2>listing.err

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

Почему порядок 2>&1 имеет значение

2>&1 означает «направить stderr туда, куда stdout направлен сейчас». Поэтому следующие команды неэквивалентны:

command >combined.log 2>&1
command 2>&1 >stdout-only.log

В первой строке stdout сначала указывает на файл, затем stderr копирует это назначение. Во второй stderr сначала копирует терминал, и лишь после этого stdout переключается на файл. Bash обрабатывает перенаправления слева направо.

Наблюдение через tee

tee читает stdin, пишет копию в файл и продолжает поток через stdout. Это полезно в CI или при долгой диагностике.

set -o pipefail
run-checks 2>&1 | tee checks.log
status=$?
printf 'checks status=%s\n' "$status"

Без pipefail status относится к tee, и падение run-checks может быть скрыто. Для добавления вместо перезаписи используется tee -a, но бесконтрольный append постепенно заполняет диск.

Ошибка и диагностика

Распространённый дефект — sudo command >protected/file: перенаправление выполняет текущий shell до запуска sudo, поэтому запись получает права обычного пользователя и падает. Проверьте владельца каталога и границу процесса. Если операция действительно разрешена, данные можно передать привилегированному tee: printf '%s\n' value | sudo tee /protected/file >/dev/null. Не превращайте этот приём в способ обходить осмысленные права.

Практика

Напишите команду, которая выдаёт stdout, stderr и status 9. Сохраните каналы отдельно, затем вместе, каждый раз проверьте содержимое и status. После этого пропустите общий поток через tee с pipefail. Объясните, почему экран и файл совпадают, а код завершения не обязан принадлежать tee.

Что важно запомнить

Частые вопросы

Чем &>file отличается от >file 2>&1?

В Bash оба варианта могут направить stdout и stderr в один файл. Второй явно показывает порядок и лучше переносится в документацию, ориентированную не только на Bash.

Почему пустой файл появился после неуспешной команды?

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

tee меняет данные?

Обычно он копирует байты без преобразования. Но ошибка записи, заполненный диск или закрытый downstream всё равно требуют проверки status и stderr.

Источники