Unix: запутанное использование команды Tee - PullRequest
14 голосов
/ 19 апреля 2009

В руководстве указано, что тройник представляет собой «фитинг для трубы». Случаи [1] смущают меня:

1. случай

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

2. случай

:w !sudo tee %

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

Ответы [ 8 ]

36 голосов
/ 19 апреля 2009

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

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

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

12 голосов
/ 19 апреля 2009

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

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

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

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

11 голосов
/ 26 августа 2016

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

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

Например

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

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

enter image description here

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

ls -l | sudo tee -a file.txt 
4 голосов
/ 24 августа 2009

Пояснения к делу

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

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

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

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

2. запуск sudo-команд с помощью Vim

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

Логика с помощью команды tee

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

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
2 голосов
/ 19 апреля 2009

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

1 голос
/ 19 апреля 2009

Я считаю, что команда tee очень полезна при отладке сценариев оболочки, содержащих длинные конвейеры. Это конец ужасного сценария оболочки, который на 10 лет запоздал для переписывания в 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, который отправляет копии вывода в несколько конвейеров, а не в несколько файлов. Он продолжает работать, даже если один из конвейеров (или стандартный вывод) завершается рано. (Смотрите мой профиль для контактной информации.)

0 голосов
/ 31 октября 2014
Команда

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

0 голосов
/ 19 апреля 2009

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

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

...