Какова цель "тройник"?
Все обычаи tee
Я когда-либо видел такие:
do_something | tee -a logfile
Или же:
do_something_else | tee logfile
Является tee
придумано для тех, кто не знает, можно ли сделать то же самое с перенаправлениями оболочки? Такие как:
do_something >> logfile
Или же:
do_something_else > logfile
Это практически то же самое, и для набора текста требуется меньше нажатий клавиш. Какие скрытые функции я не вижу в tee
?
10 ответов
Чего ты не видишь? do_something | tee -a logfile
помещает вывод в logfile
и в стандартный do_something >> logfile
помещает это только в файл журнала.
Цель tee
заключается в создании сценария с одним входом и несколькими выходами - как при пересечении "Т".
РЕДАКТИРОВАТЬ
Там были комментарии о том, как tee
позволяет более простое использование sudo
, Это не относится к делу: cat
, dd
или может быть лучше buffer
предоставьте эту возможность с лучшей производительностью, если вам не нужны несколько выходов. использование tee
за то, что он предназначен, а не за то, что он "может сделать"
Tee
не бесполезен
Может быть, вы знали это в любом случае? Если нет, то читайте дальше! Или, если вы знаете, как он работает, но не знаете, почему он существует, перейдите к концу, чтобы увидеть, как он вписывается в философию Unix.
Какова цель tee
?
В простейшем случае он берет данные на стандартный ввод и записывает их в стандартный вывод и один (или более) файл. Его сравнивают с сантехническим тройником так, как он разделяет один вход на два выхода (и два направления).
Примеры
Давайте возьмем ваш первый пример:
do_something | tee -a logfile
Это берет вывод do_something
и добавляет его в файл журнала, одновременно отображая его для пользователя. На самом деле, страница Википедии на tee
имеет это в качестве второго примера:
Чтобы просмотреть и добавить вывод команды из существующего файла:
lint program.c | tee -a program.lint
Это отобразит стандартный вывод команды lint program.c на компьютере и в то же время добавит его копию в конец файла program.lint. Если файл program.lint не существует, он создается.
В следующем примере есть другое применение: повышение разрешений:
Чтобы разрешить эскалацию разрешений:
cat ~/.ssh/id_rsa.pub | ssh admin@server "sudo tee -a /root/.ssh/authorized_keys2 > /dev/null"
В этом примере показано, как тройник используется, чтобы обойти внутреннее ограничение в
sudo
команда.sudo
не может передать стандартный вывод в файл. Сбрасывая свой стандартный поток в/dev/null
Мы также подавляем зеркальный вывод в консоли. Приведенная выше команда предоставляет текущему пользователю root доступ к серверу через ssh, установив открытый ключ пользователя в список авторизации ключей сервера.
Или, может быть, вы хотите взять выходные данные одной команды, записать их где-нибудь, а также использовать их в качестве входных данных для другой команды?
Вы также можете использовать команду tee, чтобы сохранить выходные данные команды в файл и перенаправить те же выходные данные, что и входные данные для другой команды.
Следующая команда создаст резервную копию записей crontab и передаст записи crontab в качестве команды ввода в sed, которая выполнит замену. После замены он будет добавлен в качестве нового задания cron.
$ crontab -l | tee crontab-backup.txt | sed 's/old/new/' | crontab –
(благодарю за примеры использования команды Tee)
Tee
работает с философией Unix:
Напишите программы, которые делают одно и делают это хорошо. Напишите программы для совместной работы. Написание программ для обработки текстовых потоков, потому что это универсальный интерфейс.
(Благодарность основам философии Unix)
tee
подходит всем этим:
- это делает одну вещь: создает дополнительную копию ввода
- он работает с другими программами, потому что это клей (или кусок сантехники 'T', если вы предпочитаете), который позволяет другим программам работать вместе, как в примерах выше
- это делается путем манипулирования потоком текста, заданным на стандартном вводе
Это практически то же самое, и для набора текста требуется меньше нажатий клавиш.
Это совсем не то же самое...
Следующее представляется несколько эквивалентным, но это не так:
$ echo "hi" > test.txt
$ echo "hi" | tee test.txt
hi
Критическое различие заключается в том, что первый записал данные только в именованный файл, а второй записал hi
до терминала (stdout
) и именованный файл, как показано ниже:
tee
позволяет вам записывать данные в файл и использовать их в последующем конвейере, что позволяет вам делать полезные вещи, такие как хранение данных из частично через конвейер:
grep '^look ' interesting_file.txt \
| tee interesting_lines.txt \
| sort
Или вы можете записать в файл с повышенными привилегиями, не предоставляя всему конвейеру повышенные привилегии (здесь echo
запускается как пользователь, а tee
записывает в файл как root
):
echo 0 \
| sudo tee /proc/sys/net/ipv4/ip_forward
С tee
Вы можете записать во многие файлы (и stdout
):
echo "hi" \
| tee a.txt b.txt
Также возможно использовать exec
с tee
записать весь вывод скрипта в файл, оставив при этом наблюдателя (stdout
) чтобы увидеть данные:
exec > >( tee output.log )
Т-образный фитинг. Он имеет вход и два отдельных выхода.
Другими словами, он разделяет одну трубу на две; как развилка на дороге.
Так же, tee
это труба (|
), который позволяет перенаправить ваш стандартный ввод на два отдельных выхода.
пример
Скажем, например, вы печатаете ls /
,
Вы получите вывод, который выглядит примерно так:
Applications Network Users bin dev net private tmp var
Library System Volumes cores etc home opt sbin usr
Перенаправить вывод в текстовый файл, ls / > ls.txt
и вывод не отображается в оболочке, только в результирующем текстовом файле.
Хотите увидеть вывод и одновременно передать его в текстовый файл?
Добавить tee
к твоей трубе (|
) т.е. ls / | tee ls.txt
Сравните два:
ls / > ls.txt
ls / | tee ls.txt
Нет. Вы упомянули один из немногих примеров, когда вы действительно можете перенаправить файл, используя >
а также >>
операторы.
Но Ти может сделать гораздо больше. Поскольку вы направляетесь к нему по трубопроводу, вы можете затем передавать по трубопроводу что-то еще.
Хороший пример приведен на странице википедии:
find "4DOS" wikipedia.txt | tee 4DOS.txt | sort > 4DOSsorted.txt
По сути, вы можете передавать по трубопроводу к Tee, а затем по трубопроводу от Tee к чему-то еще. Если все, что вы хотите сделать, это написать файл журнала, да, тогда вам не нужен Tee.
tee
далеко не бесполезен. Я использую это все время и рад, что это существует. Это очень полезный инструмент, если у вас есть конвейер, который вы хотите разделить. Очень простой пример - у вас есть каталог $d
что вы хотите использовать tar, а также хотите его хешировать, потому что вы параноик (как и я) и не доверяете носителю для надежного хранения данных. Вы можете сначала записать его на диск, а затем хэшировать, но это не получится, если архив будет поврежден до того, как будет хеширован. Кроме того, вам придется прочитать его, и если вы будете много работать с файлами размером в несколько сотен ГБ, вы поймете, что действительно не хотите читать их снова, если этого не требуется.
Так что я делаю просто так:
tar -c "$d" | tee >(sha256sum) >(cat > "$d"".tar") > /dev/null
Он создает тарный шарик и направляет его в тройник, который затем направляет его в две вложенные оболочки, в одной из которых он хэшируется, а в другой - записывается на диск.
Также замечательно, если вы хотите выполнить несколько операций с большим файлом:
< file.tar.gz tee >(sha256sum) >(tar -xz) /other/storage/location/file.tar.gz > /dev/null
Считывает файл один раз, хэширует его (чтобы вы могли проверить, все ли оно в порядке), извлекает его и копирует в другое место. Нет необходимости читать это три раза для этого.
Nitpick в ответе @bertieb, который гласит: В этом примере показано, как тройник используется для обхода врожденного ограничения в команде sudo. sudo не может передать стандартный вывод в файл.
Не существует внутренних ограничений, только неправильное понимание того, как обрабатывается команда.
Пример:
sudo echo 0 > /proc/sys/net/ipv4/ip_forward
Текущая оболочка анализирует командную строку. Он находит перенаправление вывода и выполняет это. Затем он выполняет команду, которая является sudo
и предоставляет оставшуюся командную строку в качестве аргументов для выполняемой команды. Если текущая оболочка не имеет прав доступа root, перенаправление вывода завершится ошибкой.
echo 0 | sudo tee /proc/sys/net/ipv4/ip_forward
Это работает, потому что перенаправление вывода отложено до tee
команда, которая на тот момент имеет права root, потому что она была выполнена через sudo
,
sudo bash -c "echo 0 > /proc/sys/net/ipv4/ip_forward"
Это работает, потому что у оболочки, выполняющей перенаправление, есть права root.
Как уже упоминали другие люди, трубопроводная продукция к tee
Команда записывает этот вывод как в файл, так и в стандартный вывод.
Я часто использую tee
когда я хочу получить выходные данные команды, выполнение которой занимает много времени, а также визуально проверить выходные данные, поскольку команда делает их доступными. Таким образом, мне не нужно ждать завершения команды, прежде чем я проверю вывод.
То, что, кажется, еще не было упомянуто (если я не пропустил это), это то, что tee
Команда также может записывать в несколько файлов одновременно. Например:
ls *.png | tee a.txt b.txt
выпишет все *.png
файлы в текущем каталоге в два разных файла (a.txt
а также b.txt
) однажды.
Фактически, вы можете набирать текст сразу в нескольких разных файлах с помощью tee
как это:
$ tee --append a.txt b.txt c.txt d.txt
These lines are appended to four different files,
and are also written to stdout.
CTRL-D
Наиболее распространенное использование tee - видеть текст на терминале одновременно с отправкой его в файл (или файлы). Формулировка вашего вопроса предполагает, что вы когда-либо пишете текст в лог-файлы. У меня есть сценарии, которые пишут списки имен файлов или каталогов для запуска файлов (для асинхронной обработки другими сценариями), и я использую tee для отправки того же контента на стандартный вывод. Весь stdout направлен на логи. Итак, у меня есть текст, где я хочу, и у меня есть запись в журнале, в которой я это сделал, все из одного утверждения 'echo'
Это также лучший метод в Unix для создания нескольких одинаковых файлов. Я иногда использую его для создания нескольких пустых файлов, как это...
:|tee file01 file02 file03
Представьте, что вы хотите записать вывод команды в файл журнала и распечатать на стандартный вывод. Когда вам нужно сделать это одновременно, тогда вам нужно tee
,
Вариант использования - иметь сценарии сборки, которые записывают всю сборку в стандартный вывод (например, для Jenkins), но одновременно важные вещи в отдельный файл журнала (для сводных электронных писем).
Вы действительно начнете скучать tee
когда вам нужно сценарий в Windows. Здесь нет tee
и это действительно раздражает.