Перенаправление и 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.
Что важно запомнить
>перезаписывает файл до запуска команды,>>добавляет данные.- Перенаправления выполняются слева направо;
2>&1копирует текущее назначение stdout. teeсохраняет наблюдаемость pipeline, но требует корректной проверки статусов.