Если вы когда-либо используете каналы и перенаправления в своей оболочке Linux, скорее всего, вам также иногда понадобится использовать утилиту tee.
Что делает Тee?
Команда, такая как
ls
ls > file123
ничего не будет отображаться на вашем экране.
Это связано с тем, что знак > перенаправляет весь вывод в файл, а не выводит его на stdout.
Теперь file123 будет заполнен содержимым, которое ранее отображалось на вашем экране.
Чтобы отобразить содержимое вашего каталога на экране и записать его в файл, вы используете две команды.
С tee вы можете сделать обе эти вещи одновременно.
ls | tee file123
Зачем использовать tee, если вы можете выполнить аналогичную команду дважды?
В приведенном выше примере вам, очевидно, не понадобится tee, если вы можете выполнить ls в обычном режиме, а затем выполнить его снова и перенаправить вывод в файл.
Однако вы столкнетесь с ситуациями, когда выходные данные будут уникальными.
Представьте себе сценарий, в котором вы пытаетесь диагностировать проблему.
Вы запускаетеdiagnose | tee error.log
Ошибки, которые вы получаете, могут быть уникальными.
Вы хотите, чтобы они отображались на экране, чтобы вы могли видеть, что происходит во время тестирования.
Но вы также хотите, чтобы эти ошибки были сохранены в файле, поэтому вы можете просмотреть их позже или вставить результат в дискуссионный форум и спросить людей об этом.
Другая часто встречающаяся ситуация, когда вам может понадобиться tee, заключается в следующем: вы хотите записать вывод команды в место, где только пользователь root может читать или писать.
Это не сработает.
/sbin/blkid > /root/somefile
Затем вы можете подумать: «Ну, конечно, просто использую sudo!» И вы удивитесь, что это тоже не сработает:
sudo blkid > /root/somefile
Это потому, что после запуска sudo blkid вы по-прежнему входите в систему как обычный пользователь без полномочий root. И ваша оболочка (обычно bash) пытается записать в /root/somefile ваши учетные данные обычного пользователя.
Чтобы решить эту проблему, вы можете использовать tee:
/sbin/blkid | sudo tee /root/somefile
Добавление текста и перенаправление ошибок
tee – полезная, но простая команда; основная команда | tee и этого иногда достаточно.
Однако есть два сценария, с которыми вы можете столкнуться, для которых потребуются следующие советы.
Первое, что нужно знать, это то, что по умолчанию он всегда перезаписывает файл.
Если вы запустите:
ls | tee somefile
а потом
ls /tmp | tee somefile
вторая команда перезапишет содержимое somefile, и вы увидите только содержимое последней выполненной команды.
Чтобы изменить это поведение, вы можете сделать так, чтобы текст добавлялся далее вместо перезаписи.
Для этого просто используйте ключ -a.
ls | tee -a somefile
Второе, что нужно знать, это то, что не все результаты одинаковы.
Сообщения об ошибках обрабатываются по-разному, и хотя они появляются на экране, они не считаются стандартными, поэтому они не будут пойманы tee.
(Они считаются stderr.) Вот пример на grep.
grep -r L2TP /etc | tee somefile
Система будет отображать что-то вроде следующего изображения.
Сообщения с отказом в доступе пишутся в stderr.
Единственное, что пишется на стандартный вывод – это выделенный текст.
Вот почему вы заметите, что содержимое «somefile» – это то, что показано на рисунке ниже.
В этом случае, когда для поиска текста используется grep, полезно, чтобы сообщения об ошибках не перенаправлялись в файл.
Они просто заполнили бы файл ненужным мусором.
Вам нужно только увидеть найденные результаты.
Но когда вам нужны сообщения об ошибках, используйте 2>&1, который перенаправляет stderr в stdout.
grep -r L2TP /etc 2>&1 | tee somefile
С помощью этой команды вы заметите, что somefile теперь также содержит сообщения об ошибках.
Заключение
Надеемся, что этот урок охватывает все, что вам нужно, чтобы извлечь максимальную пользу из команды tee.
Но если вы столкнулись с ситуацией, когда вы застряли с чес-либо, оставьте комментарий ниже, и мы сможем вам помочь.