Linux / Comando tee: mostrar e salvar a saída de um pipeline
tee copia a entrada padrão para a saída padrão e para um ou mais arquivos ao mesmo tempo. Assim, você pode acompanhar a saída de um comando enquanto a salva, ou registrar uma etapa intermediária de um pipeline. Por padrão, tee sobrescreve o arquivo de destino; use -a para acrescentar ao final.
A saída padrão vai para a tela quando não há outro comando ou redirecionamento depois de tee. Se houver um próximo comando no pipeline, esse comando recebe a cópia; o conteúdo do arquivo pode ser maior do que a parte mostrada na tela. O erro padrão é um fluxo separado e precisa ser encaminhado explicitamente quando também deve ser salvo.
Sintaxe e cuidado com sobrescrita
comando | tee [opção...] arquivo [arquivo...]
Essa linha descreve a sintaxe: substitua comando, opções e nomes pelos valores desejados. O pipe (|) envia a saída padrão do comando anterior à entrada de tee. Você pode informar vários arquivos de destino. Consulte tee --version, tee --help ou man tee; as opções deste guia seguem o GNU Coreutils.
Escolha um destino novo para preservar um arquivo existente, ou use -a quando acrescentar for o comportamento pretendido. O ajuste de shell set -C, também chamado noclobber, protege certos redirecionamentos feitos pelo shell; ele não impede tee de abrir e sobrescrever um arquivo passado como argumento. Confirme o destino e guarde uma cópia de dados importantes antes de substituí-los.
Preparar os dados e salvar a saída de date
Em um terminal Bash dedicado ao exercício, execute o bloco inteiro em uma pasta onde possa criar arquivos. Ele cria uma pasta exclusiva, prepara names.txt e grava a data em run-time.txt. && interrompe as próximas etapas da preparação se houver uma falha. Continue na mesma sessão, dentro dessa pasta.
tee_demo=$(mktemp -d ./tee-demo.XXXXXX) &&
cd "$tee_demo" &&
export LC_ALL=C &&
printf 'Zeca\nAna\nBia\n' > names.txt &&
date | tee run-time.txt
A data e a hora mostradas na tela são as mesmas gravadas em run-time.txt. O texto exato depende do relógio e do fuso do ambiente; não espere uma data fixa. Confira com cat run-time.txt. O ajuste export LC_ALL=C mantém o mesmo ambiente para a ordenação dos próximos exemplos; ao fechar a sessão dedicada, ele deixa de afetar comandos futuros.
Acrescentar outra linha com -a
Execute novamente date, acrescentando sua saída ao arquivo já criado:
date | tee -a run-time.txt
A tela mostra somente a nova linha de data. O arquivo passa a conter a linha anterior e a nova, nessa ordem. cat run-time.txt permite conferir ambas. Se você repetir a versão sem -a, o arquivo será substituído pela nova saída. As datas podem ser iguais se os comandos forem executados muito próximos.
Salvar uma etapa intermediária e continuar o pipeline
names.txt contém Zeca, Ana e Bia, nessa ordem. Para ordenar, salvar o resultado e enviar a saída para head:
sort names.txt | tee names.sorted | head
A saída mostra Ana, Bia e Zeca, uma por linha, e names.sorted contém essas mesmas três linhas. O comando sort ordena; tee grava e encaminha; head mostra as primeiras dez linhas por padrão. Neste arquivo de três linhas, head lê a entrada toda.
Com uma entrada grande, head pode encerrar antes de ler tudo. O GNU tee pode então encontrar um pipe fechado e terminar antes de concluir a gravação no arquivo. Se a intenção é continuar gravando mesmo quando o consumidor do pipe sai cedo, use tee -p, por exemplo sort names.txt | tee -p names-complete.sorted | head. A opção ajusta o tratamento do erro de pipe e permite continuar nas saídas restantes; ela não corrige falhas do comando que produz os dados nem erros de gravação em disco.
Conferir uma saída determinística
Para comparar diretamente o conteúdo enviado à tela e ao arquivo, use uma linha fixa:
printf 'status=ok\n' | tee result.txt
A tela e result.txt recebem:
status=ok
Confira com cat result.txt. Depois, printf 'status=done\n' | tee -a result.txt mostra status=done e acrescenta essa segunda linha ao arquivo. Para criar duas cópias novas da mesma saída, printf 'status=ok\n' | tee copy-a.txt copy-b.txt grava uma linha em cada arquivo e também a mostra na saída padrão.
Incluir o erro padrão quando necessário
No Bash, (printf 'ok\n'; printf 'erro\n' >&2) | tee stdout.log grava somente ok em stdout.log. O texto erro continua no erro padrão do grupo de comandos e pode aparecer no terminal sem ter sido salvo nesse arquivo.
Para reunir os dois fluxos antes de tee, use (printf 'ok\n'; printf 'erro\n' >&2) 2>&1 | tee combined.log. Nesse exemplo sequencial, combined.log contém ok e erro, uma linha por mensagem, e ambas também seguem pela saída padrão. Em programas com execução concorrente ou buffers próprios, a ordem das mensagens observadas pode depender do programa.
Verificar falhas do pipeline
No Bash, o status de um pipeline normalmente vem do último comando. Assim, um head bem-sucedido pode esconder uma falha anterior em tee. Imediatamente após o pipeline, printf '%s\n' "${PIPESTATUS[@]}" mostra os status individuais, na ordem dos comandos. Execute essa consulta antes de qualquer outro comando, pois o array PIPESTATUS é atualizado a cada execução.
Para fazer o status geral considerar falhas anteriores, você pode usar (set -o pipefail; sort names.txt | tee -p names-complete-checked.sorted | head). O ajuste vale apenas para o subshell entre parênteses. Em seguida, consulte echo "$?" imediatamente. Um status 0 indica sucesso dos comandos desse pipeline, mas a validade dos dados ainda depende do produtor e da tarefa. Quando for essencial guardar toda a saída, confira também o arquivo produzido.
Na verificação com GNU tee 8.32 no Bash do Git para Windows, foram conferidos gravação, acréscimo, múltiplas saídas, separação dos fluxos, falha ao abrir um destino e o comportamento de um consumidor que termina cedo. A semântica de -p e os recursos do shell devem ser conferidos na implementação usada no seu sistema.
Entender permissões e o uso de sudo
Em um sistema Linux com sudo configurado, o padrão descritivo comando | sudo tee arquivo faz tee abrir o destino com os privilégios concedidos por sudo. Já em sudo comando > arquivo, o redirecionamento é feito pelo shell atual antes de executar o comando com sudo, e pode falhar por falta de permissão.
Esse uso exige autorização para o comando e cuidado com o destino: tee continua sobrescrevendo por padrão, e a elevação não corrige um caminho errado. A entrada também segue para a saída padrão. Se a cópia na tela for indesejada, redirecione a saída de tee para /dev/null no ambiente Linux. Verifique o resultado e evite enviar dados que não devem aparecer no terminal ou nos registros.
Opções principais
| Opção | Uso |
|---|---|
-a |
Acrescenta ao final dos destinos em vez de sobrescrevê-los. |
-i |
Ignora o sinal de interrupção; não é uma opção geral para ignorar erros. |
-p |
No GNU tee, ajusta o tratamento de erros de pipe para continuar em saídas restantes quando apropriado. |
Pergunta frequente
tee salva o erro padrão automaticamente?
Não. Ele copia apenas o que recebe na entrada padrão. Se também quiser gravar o erro padrão do comando anterior, reúna esse fluxo à saída padrão antes do pipe com o redirecionamento adequado, como 2>&1 no Bash, e confira o arquivo resultante.
Documentação oficial
Consulte a página de manual de tee publicada pelo Debian, a documentação do GNU tee e as explicações do Bash sobre pipelines e pipefail e redirecionamentos.




