tee в Linux — показывать вывод и сохранять в файл

Что делает команда tee
Термины в одну строку:
- stdout — стандартный вывод программы (обычно экран терминала).
- stderr — стандартный поток ошибок (сообщения об ошибках).
- redirect — перенаправление потока в файл или в другой процесс.
Если вы запустите простую команду:
lsВы увидите список файлов в каталоге — этот список идет в stdout и попадает на экран.
Если вы перенаправите вывод в файл:
ls > file123То экран останется пустым, а вывод запишется в file123.
Команда tee позволяет сделать и то, и другое одновременно:
ls | tee file123tee читает данные из stdin и пишет их в указанные файлы и в stdout. Это удобно при отладки, сборе логов и при работе с правами доступа.
Зачем использовать tee вместо повторного запуска команды
Иногда вывод команды уникален и изменяется при каждом запуске (например, диагностические сообщения, ошибки по мере теста). В таких случаях повторный запуск не воспроизведёт те же данные. Команда
diagnose | tee error.logпокажет ошибки на экране и одновременно сохранит их в error.log для последующего анализа или публикации.
Другой частый пример — запись вывода в файл, доступный только root. Простая попытка:
/sbin/blkid > /root/somefileупадёт с «Permission denied», если вы не root. Если вы попробуете выполнить с sudo:
sudo blkid > /root/somefileто перенаправление (>) будет выполняться вашей оболочкой от имени обычного пользователя, и ошибка сохранится. Правильное решение — передать запись в tee, запущенную через sudo:
/sbin/blkid | sudo tee /root/somefileЕсли вы хотите подавить отображение вывода на экран и записать только в файл, добавьте перенаправление stdout tee в /dev/null:
/sbin/blkid | sudo tee /root/somefile > /dev/nullДобавление текста без перезаписи и работа с ошибками
По умолчанию tee перезаписывает файл. Чтобы дописывать в конец файла, используйте флаг -a:
ls | tee -a somefileОшибка и обычный вывод — разные потоки. stdout попадает в tee, а stderr — нет. Пример:
grep -r L2TP /etc | tee somefile
Сообщения «Permission denied» идут в stderr и поэтому не окажутся в somefile. Если вам нужны и stdout, и stderr в файле, перенаправьте stderr в stdout перед tee:
grep -r L2TP /etc 2>&1 | tee somefile
Теперь both потоков будут сохранены в somefile.
Быстрый справочник по флагам и шаблонам использования
- -a — дописывать (append) вместо перезаписи.
- -i — игнорировать сигналы прерывания (полезно в некоторых сценариях запуска).
Полезные шаблоны:
- Сохранить stdout и stderr с меткой времени (требуется утилита ts из moreutils, либо простая замена через awk):
mycommand 2>&1 | ts '[%Y-%m-%d %H:%M:%S]' | tee -a run.log(Если ts недоступна, можно добавить метки вручную через awk.)
- Запись в защищённый файл от root:
command | sudo tee /root/secure.log- Не показывать вывод на экран, только файл:
command | sudo tee /root/logfile > /dev/null- Разделение вывода на два файла и на экран:
command | tee file1 file2 | other_commandАльтернативные подходы
- sudo с оболочкой: если нужно записать только один файл, можно обернуть команду в sudo sh -c:
sudo sh -c 'blkid > /root/somefile'- Процессное подстановление (bash):
command > >(tee file)- Использовать screen/tmux для записи сессии с последующим экспортом.
Каждый подход полезен в зависимости от контекста: sudo sh -c удобен для одиночных операций; tee удобен для потоковой записи и отображения одновременно.
Методика: как безопасно собирать диагностические логи
- Определите, нужен ли вам stderr (сообщения об ошибках) вместе со stdout.
- Выберите режим записи: перезапись или дописывание (-a).
- Для системных путей используйте sudo tee.
- Убедитесь, что логи не содержат чувствительных данных; при необходимости маскируйте их.
- Храните логи с корректными правами доступа (chmod, chown).
Пример команды, пригодной для диагностики:
myservice --verbose 2>&1 | tee -a /var/log/myservice/diagnostic-$(date +%F).logЧеклист по ролям
Системный администратор:
- Использовать sudo tee для записи в защищённые каталоги.
- Настроить ротацию логов (logrotate) для файлов, создаваемых tee.
- Проверять права доступа (chmod/chown) для логов.
Разработчик:
- Сохранять вывод тестов командой tee для последующего анализа.
- Объединять stdout и stderr при поиске редких ошибок.
Саппорт/инженер по поддержке:
- Попросить пользователя выполнить команду с tee и прислать файл лога.
- Давать инструкции с точными командами и избегать путаницы с кавычками и перенаправлением.
Распространённые ошибки и способы их исправить
- «Permission denied» при > file — используйте sudo tee или sudo sh -c.
- Отсутствуют сообщения об ошибках в файле — значит stderr не был перенаправлен; используйте 2>&1.
- Файл перезаписывается — забыл флаг -a.
- Двойной вывод на экран и файл мешает чтению — перенаправьте stdout tee в /dev/null.
- tee не найден — установите coreutils (чаще всего tee уже доступен) или используйте альтернативы.
Важно: логи могут содержать личные или конфиденциальные данные. Перед отправкой такого файла в публичные форумы просмотрите и при необходимости замаскируйте чувствительную информацию.
Когда tee не подойдёт
- Когда нужно асинхронно собирать вывод со множества удалённых хостов — лучше использовать централизованные системы логирования (rsyslog, ELK, Fluentd).
- Когда требуется транзакционная целостность записи (например, база данных) — логирование через tee не гарантирует атомарность на уровне приложения.
Маленькая памятка (cheat sheet)
- Перезаписать и показать: command | tee file
- Дописать и показать: command | tee -a file
- Сохранить stdout+stderr: command 2>&1 | tee file
- Записать в root: command | sudo tee /root/file
- Тишина на экране, только файл: command | sudo tee /root/file > /dev/null
Диаграмма принятия решения
flowchart TD
A[Нужно записать вывод?] -->|Нет| B[Не использовать tee]
A -->|Да| C[Нужен stderr в файле?]
C -->|Да| D[Добавить 2>&1 перед |]
C -->|Нет| E[Не добавлять stderr]
D --> F[Нужен доступ к защищённому файлу?]
E --> F
F -->|Да| G[Использовать sudo tee]
F -->|Нет| H[Обычный tee]
G --> I[Если не нужен вывод на экран: > /dev/null]
H --> I
I --> J[Готово]Краткое резюме
Команда tee проста, но полезна: она дублирует stdout в файл и на экран. Используйте флаг -a для дозаписи, перенаправляйте stderr в stdout (2>&1), если нужны ошибки, и применяйте sudo tee для записи в защищённые области. Перед отправкой логов извлекайте или маскируйте конфиденциальные данные.
Если остались вопросы или возник специфический кейс — опишите шаги и результаты, и мы поможем подобрать точную команду.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента