Unix: запутанное использование команды Tee

В мануале указано, что тройник - это инструмент для "фитингов". Меня смущают случаи [1]:

<сильный>1. случай

echo "foo bar" | sudo tee -a /path/to/some/file

<сильный>2. случай

:w !sudo tee %

Трудно понять логику тройника из кейсов. Как работает тройник?


person Léo Léopold Hertz 준영    schedule 18.04.2009    source источник
comment
:w !sudo tee % stackoverflow.com/a/7078429/739331   -  person Mohammed H    schedule 09.05.2015
comment
Вот краткий обзор Tee grizzlybit.info/blog/how-to- использовать тройник в Linux   -  person zubair1024    schedule 23.11.2020


Ответы (8)


tee обычно используется для разделения вывода программы, чтобы его можно было одновременно отображать и сохранять в файле. Команду можно использовать для захвата промежуточных выходных данных до того, как данные будут изменены другой командой или программой. Команда tee читает стандартный ввод, а затем записывает его содержимое в стандартный вывод. Одновременно копирует результат в указанные файлы или переменные.

tee [OPTION]... [FILE]...

Например

tee [ -a ] [ -i ]... [ File ]...
  • -a Добавляет вывод в конец файла вместо записи поверх него.

  • -i Игнорирует прерывания.

введите описание изображения здесь

С sudo и добавлением к файлу вашего примера в вопросе

ls -l | sudo tee -a file.txt 
person Girdhar Singh Rathore    schedule 26.08.2016
comment
Может быть, тогда вы сможете показать, как вы перенаправляете вывод также на less, когда вы уже используете sudo. - person Léo Léopold Hertz 준영; 26.08.2016

tee используется для разделения конвейера команд, что позволяет сохранять вывод команды в файл и отправлять его дальше по конвейеру. В первом примере вы дали::

echo "foo bar" | sudo tee -a /path/to/some/file

"foo bar" будет выведено на стандартный вывод и добавлено к /path/to/some/file. Думайте о тройнике как о тройнике в трубе, разделяющем выход на две другие трубы.

person Rick Copeland    schedule 18.04.2009
comment
Отсюда и название :-) - person Joey; 28.09.2009

tee копирует stdin в stdout (как и cat) и дополнительно записывает все в указанный файл. Использование его таким образом с sudo позволяет помещать информацию в привилегированный режим и - в то же время - контролировать, пошли ли туда нужные вещи.

Также обратите внимание, что из-за того, как перенаправление обрабатывается в оболочке, почти эквивалентно

sudo echo "foo bar" > /path/to/some/file

не будет работать, так как перенаправление будет выполнено вызывающим пользователем, а не sudo целевым пользователем.

person David Schmitt    schedule 18.04.2009
comment
что делать, если данные стандартного вывода слишком велики, как они помещают данные в файл? по размеру или по времени? - person Shantesh; 07.01.2016

Пояснения к случаям

<сильный>1. повышение разрешений с помощью команд sudo- и -tee

Пример касается не только логики, но и условности. Это показывает соглашение об эскалации разрешений:

echo "Body of file..." | sudo tee root_owned_file > /dev/null

В этом примере показано, как tee используется для обхода внутреннего ограничения команды sudo. sudo не может передать стандартный вывод в файл. Сбрасывая поток stdout в /dev/null, мы также подавляем зеркальный вывод в консоли.

<сильный>2. запуск sudo-команд с Vim

Поскольку вы можете использовать Sudo-команды с Vim, вы можете использовать команду, если вы забыли запустить ее как sudo. Это полезно в таких местах, как /etc/init.d/, где вы найдете файлы только для чтения.

Логика с командой tee

Это похоже на ветку в Git или лучше, пожалуйста, см. аналогия T Рика Коупленда. Надеюсь, модифицированный пример (original) поможет понять его использование:

curl "http://en.wikipedia.org/wiki/Pipeline_(Unix)" | tee original_site | sed 's/[^a-zA-Z ]/ /g' | tr 'A-Z ' 'a-z\n' | grep '[a-z]' | sort -u | comm -23 - /usr/share/dict/words
person Léo Léopold Hertz 준영    schedule 24.08.2009

Помните, что цель tee не ограничивается обычными файлами, а может быть устройствами, FIFO и т. д. Кроме того, вы можете подключиться к другому вызову tee и т. д. :-)

person Chris Jester-Young    schedule 18.04.2009

Я считаю, что команда tee очень полезна при отладке сценариев оболочки, содержащих длинные конвейеры. Это конец жуткого скрипта оболочки, который уже десять лет должен быть переписан на Perl, но он все еще работает. (Последний раз он был изменен в 1998 году.)

# If $DEBUG is yes, record the intermediate results.
if [ "$DEBUG" = yes ]
then
    cp $tmp.1 tmp.1
    cp $tmp.2 tmp.2
    cp $tmp.3 tmp.3
    tee4="| tee tmp.4"
    tee5="| tee tmp.5"
    tee6="| tee tmp.6"
    tee7="| tee tmp.7"
fi

# The evals are there in case $DEBUG was yes.
# The hieroglyphs on the shell line pass on any control arguments
# (like -x) to the sub-shell if they are set for the parent shell.
for file in $*
do
    eval sed -f $tmp.1 $file                $tee4 |
    eval sed -f $tmp.3                      $tee5 |
    eval sh ${-+"-$-"}                      $tee6 |
    eval sed -f $tmp.2                      $tee7 |
    sed  -e '1s/^[  ]*$/--@/' -e '/^--@/d'
done

Три запущенных sed-скрипта ужасны - я не планирую их показывать. Это также полуприличное использование eval. Обычные имена временных файлов ($tmp.1 и т. д.) сохраняются под фиксированным именем (tmp.1 и т. д.), а промежуточные результаты сохраняются в tmp.4 .. tmp.7. Если бы я обновлял команду, она использовала бы «"$@#"» вместо «$*», как показано. И, когда я его отлаживаю, то в списке аргументов есть только один файл, поэтому трампание файлов отладки для меня не проблема.

Обратите внимание, что если вам нужно это сделать, вы можете создать несколько копий ввода одновременно; нет необходимости передавать одну команду tee в другую.

Если кому-то это нужно, у меня есть вариант tee под названием tpipe, который отправляет копии вывода в несколько конвейеров вместо нескольких файлов. Он продолжает работать, даже если один из конвейеров (или стандартный вывод) завершается досрочно. (См. мой профиль для контактной информации.)

person Jonathan Leffler    schedule 19.04.2009

tee просто отражает вывод в файл, который можно указать в качестве аргумента tee.

В случае, если вы показываете, что tee вызывается как суперпользователь (через sudo), и его единственная цель - вместо этого записать файл в качестве суперпользователя, если пользователь выполняет эхо.

person lothar    schedule 18.04.2009

Команда tee просто создает N+1 файлов без файлов, 1 копия передается на стандартный вывод, а другие — на аргументы, предоставленные tee (т. е. файлы), где N: количество переданных tee аргументов

person Abhishek choudhary    schedule 31.10.2014