Todos os usos que tee
eu já vi eram tais:
do_something | tee -a logfile
Ou:
do_something_else | tee logfile
Foi tee
inventado para aqueles que não sabem que você pode fazer o mesmo com redirecionamentos de pipe de shell? Tal como:
do_something >> logfile
Ou:
do_something_else > logfile
É praticamente o mesmo e são necessários menos toques no teclado para digitar. Em quais recursos ocultos não estou vendo tee
?
tee
e o redirecionamento de E / S ? O fato de dizer “ redirecionamentos de pipe de shell como e ” não é um ponto a seu favor e é um argumento para o fechamento como pouco claro. Mas, na verdade, ele faz várias perguntas: “Qual é o objetivo ?”, “Foi inventado para aqueles que não sabem que você pode fazer o mesmo com os redirecionamentos de pipe de shell?” E “Em quais recursos ocultos não estou vendo ?”. Pelo menos duas dessas perguntas são muito amplas.>
>>
tee
tee
tee
Respostas:
O que você não vê é que
do_something | tee -a logfile
coloca a saída emlogfile
e para stdout, enquanto ado_something >> logfile
coloca apenas no arquivo de log.O objetivo
tee
é produzir um cenário de múltiplas entradas e uma entrada - exatamente como em um cruzamento em 'T'.EDITAR
Houve comentários em torno de como
tee
possibilita o uso mais aparente desudo
. Isso não vem ao caso:cat
,dd
ou talvez seja melhorbuffer
oferecer esta possibilidade com melhor desempenho, se você não precisa as várias saídas. Usetee
para o que foi projetado, não para o que "também pode fazer"fonte
tee
pode até aceitar vários argumentos e gravar em muitos arquivos de uma só vez.cat
maneira direta em vez detee
por exemploecho /var/work/core.%p | sudo tee /proc/sys/kernel/core_pattern
?echo /var/work/core.%p | sudo cat > /proc/sys/kernel/core_pattern
não funciona, porque o redirecionamento é processado pelo shell não sudo. Quanto add
,echo /var/work/core.%p | sudo dd of=/proc/sys/kernel/core_pattern
funciona, masdd
muitas vezes é uma ferramenta sobrecarregada, capaz de causar grandes danos, especialmente sobsudo
. Quantobuffer
, não é instalado por padrão em qualquer uma das distros baseadas no Ubuntu RedHat- ou eu tenho que entregar (ou MacOS) ...cat
nem o/bin/cat
trabalho para mim nesta situação. Não importa de ondecat
vem - o>
ainda será tratado pelo shell de nível superior (não sudo). A vantagem detee
maiscat
nesta situação é que ele permite que o arquivo de saída para ser passado como um parâmetro de linha de comando (e não um redirecionamento).dd
é certamente uma opção viável, embora eu ainda prefiratee
isso #cat
etee
como builtins? E qual versão dosudo
pode executar shell builtins?Tee
não é inútilTalvez você soubesse disso, afinal? Se não, continue a ler! Ou se você sabe como funciona, mas não sabe ao certo por que existe, pule para o final para ver como ele se encaixa na filosofia do Unix.
Qual é o propósito
tee
?Na sua forma mais simples, coleta dados na entrada padrão e grava-os na saída padrão e em um (ou mais) arquivos. Foi comparado a uma peça de T do encanamento na maneira como divide uma entrada em duas saídas (e duas direções).
Exemplos
Vamos dar o seu primeiro exemplo:
Isso pega a saída
do_something
e a anexa ao arquivo de log, enquanto também a exibe ao usuário. De fato, a páginatee
da Wikipedia apresenta esse como o segundo exemplo:O exemplo a seguir tem outro uso: escalação de permissões :
Ou talvez você queira pegar a saída de um comando, escrever isso em algum lugar e também usá-lo como entrada para outro comando?
( exemplos de uso do comando Tee para crédito )
Tee
trabalha com a filosofia Unix:(Crédito ao básico da filosofia Unix )
tee
serve para todos:fonte
sudo tee -a
é provavelmente uma inovação mais recente (eu a vi pela primeira vez nos guias / wikis do Ubuntu, especialmente para definir coisas/proc/sys
, porque a mudança para o Ubuntu ocorreu quando eu mudei para umsudo
sistema baseado (como o Ubuntu é configurado por padrão) em vez de usarsu
com um senha root). Eu acho quetee
é anteriorsudo
, então não é uma razão paratee
existir. Você não precisatee
disso, é simplesmente mais curto para digitar interativamentesudo sh -c 'cat > output'
.tee
alimentar dois gasodutos, comofoo | tee >(pipe2) | pipe1
. Ou outro divertido éffmpeg ... |& tee /dev/tty | sed 's/.*\r// > encode.log
ver as atualizações da linha de status interativamente no tty, enquanto remove as "linhas" que terminam com retorno de carro em vez de nova linha para o log real. (ou seja, filtre as atualizações da linha de status). Em geral, você pode colar um localtee /dev/tty
em qualquer lugar no pipeline como uma impressão de depuração.>
e configura o redirecionamento antes que o sudo seja obtidoexec
, então definitivamente não é uma limitação do sudo que ele não lida com coisas que nunca vê. :) Normalmente, tento me referir a isso como "o fluxo de trabalho do sudo" ou algum termo semelhante ao explicá-lo, em vez de descrever o próprio sudo.sudo tee -a
IMHO é um abuso de tee. Usesudo cat
,sudo dd
ou (com melhor desempenho em muitos casos)sudo buffer
se você não precisa as várias saídas.Não é a mesma coisa ...
O seguinte parece ser um pouco equivalente, mas não é:
A diferença crítica é que o primeiro gravou os dados apenas no arquivo nomeado, enquanto o último gravou
hi
no terminal (stdout
) e no arquivo nomeado, conforme mostrado abaixo:tee
permite gravar os dados em um arquivo e usá-los em um pipeline posterior, permitindo que você faça coisas úteis - como impedir que os dados parem no meio de um pipeline:Ou, você pode gravar em um arquivo com privilégios elevados, sem conceder privilégios elevados a todo o pipeline (aqui
echo
é executado como usuário, enquantotee
grava no arquivo comoroot
):Com
tee
, você pode gravar em muitos arquivos ( estdout
):Também é possível usar
exec
comtee
para gravar toda a saída de um script em um arquivo, enquanto ainda permite que um observador (stdout
) veja os dados:fonte
exec > >(tee "$LOGFILE") 2>&1
de um script bash que permite que o script produza stdout e stderr para ambos, stdout e o arquivo apontado por$LOGFILE
.2>&1
para soltar a saída e errar para arquivos txt no Windows.Este é um tee:
Um encaixe de tubo em forma de T. Possui uma entrada e duas saídas separadas.
Em outras palavras, ele divide um tubo em dois; como uma bifurcação na estrada.
Da mesma forma,
tee
é um pipe (|
) que permite redirecionar sua entrada padrão para duas saídas separadas.Exemplo
Digamos, por exemplo, que você digite
ls /
.Você obterá uma saída parecida com:
Redirecione a saída para um arquivo de texto,,
ls / > ls.txt
e nenhuma saída será exibida no shell, apenas no arquivo de texto resultante.Deseja ver a saída E transmiti-la para um arquivo de texto ao mesmo tempo?
Adicione a
tee
ao seu pipe (|
) ou seja:ls / | tee ls.txt
Compare os dois:
fonte
Não. Você mencionou um dos poucos exemplos em que você poderia realmente redirecionar para o arquivo usando
>
e>>
operadores.Mas Tee pode fazer muito mais. Como você usa isso, pode usar outro método.
Um bom exemplo está listado na página da wikipedia :
Basicamente, você pode canalizar para Tee, para que possa passar de Tee para outra coisa. Se tudo o que você quer fazer é escrever um arquivo de log, sim, então você realmente não precisa do Tee.
fonte
tee
está longe de ser inútil. Eu uso o tempo todo e fico feliz que ele exista. É uma ferramenta muito útil se você tiver um pipeline que deseja dividir. Um exemplo muito simples é que você tem algum diretório$d
que deseja tar e também o quer fazer hash porque é paranóico (como eu sou) e não confia no meio de armazenamento para armazenar os dados de maneira confiável. Você pode gravá-lo primeiro no disco e depois fazer o hash, mas isso falharia se o arquivo fosse corrompido antes de ser hash. Além disso, você precisaria lê-lo e se trabalhar com arquivos com várias centenas de GB de tamanho, saberá que realmente não deseja lê-los novamente, se não for necessário.Então, o que eu faço é simplesmente isso:
Ele cria a bola de alcatrão e a conduz ao tee, o que a leva a duas subcascas, em uma das quais é hash e na outra, gravada no disco.
Também é ótimo se você deseja executar várias operações em um arquivo grande:
Lê o arquivo uma vez, faz o hash (para que você possa verificar se ainda está como deveria estar), extrai-o e copia-o para um local diferente. Não é necessário ler três vezes para isso.
fonte
tee
não cria os subshells; O chamado é executado shellsha5sum
ecat
e se conecta a sua saída para o arquivo descritores que são passados paratee
. Além disso, um uso inútil decat
; você pode usar o redirecionamento de entrada para tertee
lido diretamentefile.tar.gz
.cat
é amor.cat
é vida.< file.tar.gz tee >(sha256sum) ...
se estiver preocupado com a ordem lexical dos redirecionamentos. Isso não muda o fato de que não há necessidade de um processo totalmente separado apenas para alimentar um único arquivotee
.cat
é relativamente baixo. O custo de 100 GiB extras de chamadas do sistema write + read definitivamente desperdiça tempo extra da CPU e largura de banda da memória para o exemplo proposto de um arquivo enorme. Lembre-se de que a largura de banda da memória é um recurso compartilhado em todos os núcleos, sem mencionar a poluição extra do cache L3 dessa cópia. Em um x86 com a mitigação Spectre + Meltdown ativada, as chamadas do sistema são mais caras do que costumavam ser. Você está gastando uma quantidade mensurável de tempo extra da CPU ao longo dessa cópia. Também>(cat > foo)
não é mais fácil entender do quefoo
IMO.Nitpick na resposta de @ bertieb que diz Este exemplo mostra tee sendo usado para ignorar uma limitação inerente no comando sudo. O sudo não pode canalizar a saída padrão para um arquivo.
Não há limitação inerente, apenas um mal-entendido de como o comando é processado.
Exemplo:
sudo echo 0 > /proc/sys/net/ipv4/ip_forward
O shell atual analisa a linha de comando. Ele encontra o redirecionamento de saída e executa isso. Em seguida, ele executa o comando, que é o
sudo
e fornece a linha de comando restante como argumentos para o comando executado. Se o shell atual não tiver permissões de root, o redirecionamento de saída falhará.echo 0 | sudo tee /proc/sys/net/ipv4/ip_forward
Isso funciona porque o redirecionamento de saída é adiado para o
tee
comando, que nesse momento possui permissões de root porque foi executado viasudo
.sudo bash -c "echo 0 > /proc/sys/net/ipv4/ip_forward"
Isso funciona porque o shell que está fazendo o redirecionamento possui permissões de root.
fonte
sudo
para o comando, mas não para o arquivo a ser emitidos e o redirecionamento funciona muito bem:sudo foo-needs-privilege > /tmp/this-output-file-doesnt
Como outras pessoas mencionaram, canalizar a saída para o
tee
comando grava essa saída em um arquivo e em stdout.Costumo usar
tee
quando quero capturar a saída de um comando que leva muito tempo para ser executado, enquanto também quero inspecionar visualmente a saída à medida que o comando a disponibiliza. Dessa forma, não preciso esperar que o comando termine de executar antes de inspecionar a saída.O que parece não ter sido mencionado ainda (a menos que eu tenha perdido), é que o
tee
comando também pode gravar em vários arquivos ao mesmo tempo. Por exemplo:gravará todos os
*.png
arquivos no diretório atual em dois arquivos diferentes (a.txt
eb.txt
) ao mesmo tempo.Na verdade, você pode digitar texto em vários arquivos diferentes ao mesmo tempo, com o
tee
seguinte:fonte
O uso mais comum do tee é ver o texto no terminal ao mesmo tempo em que você o envia para o arquivo (ou arquivos). O texto da sua pergunta pressupõe que você apenas escreve texto em arquivos de log. Tenho scripts que escrevem listas de nomes de arquivos ou diretórios para acionar arquivos (a serem processados por outros scripts de forma assíncrona) e uso tee para enviar o mesmo conteúdo ao stdout. Todo o stdout é direcionado para os logs. Então, eu tenho o meu texto onde eu quero e tenho uma entrada de registro que fiz isso, tudo a partir de uma única instrução 'eco'
tee também é o melhor método no Unix para criar vários arquivos idênticos. Eu uso ocasionalmente para criar vários arquivos vazios, como este ...
fonte
touch
? (mais imediatamente óbvio o que está acontecendo)touch
não truncará os arquivos se eles já existirem, mas apenas atualizará seus carimbos de data e hora e deixará o conteúdo como está; mastee
irá truncá-los. Além disso, fazendorm
+touch
é diferentetee
(pense sobre hardlinks e links simbólicos)truncate -s 0
? :-)Imagine, você deseja gravar a saída de um comando em um arquivo de log E imprimir em stdout. Quando você precisar fazer isso ao mesmo tempo, precisará
tee
.Um caso de uso é ter scripts de compilação que escrevam toda a compilação no stdout (por exemplo, para Jenkins), mas coisas importantes ao mesmo tempo em um arquivo de log separado (para emails de resumo).
Você realmente começará a faltar
tee
quando precisar fazer um script no Windows. Não existetee
e isso é realmente irritante.fonte
tee
. O Cmd nunca foi destinado a scripts sérios - era para isso que o VBS era. O Powershell é a nova ferramenta de script essencial. É verdade que o Cmd ainda é bastante poderoso, mas as ferramentas de linha de comando são muito poucas.