Como redirect a saída para um arquivo e stdout

No bash, chamar foo exibiria qualquer saída desse comando no stdout.

Chamar foo > output redirectia qualquer saída desse comando para o arquivo especificado (neste caso, ‘output’).

Existe uma maneira de redirect a saída para um arquivo e tê-lo exibido no stdout?

O comando que você quer é chamado tee :

 foo | tee output.file 

Por exemplo, se você se importa apenas com stdout:

 ls -a | tee output.file 

Se você quiser include stderr, faça:

 program [arguments...] 2>&1 | tee outfile 

2>&1 redireciona o canal 2 (stderr / erro padrão) para o canal 1 (saída padrão / saída padrão), de tal forma que ambos são gravados como stdout. Ele também é direcionado para o arquivo de saída fornecido a partir do comando tee .

Além disso, se você quiser append ao arquivo de log, use tee -a como:

 program [arguments...] 2>&1 | tee -a outfile 
 $ program [arguments...] 2>&1 | tee outfile 

2>&1 despeja os streams stderr e stdout. tee outfile pega o stream que recebe e grava na canvas e no arquivo “outfile”.

Isso é provavelmente o que a maioria das pessoas está procurando. A situação provável é que algum programa ou script esteja trabalhando bastante por um longo tempo e produzindo muitos resultados. O usuário quer verificá-lo periodicamente quanto ao progresso, mas também deseja que a saída seja gravada em um arquivo.

O problema (especialmente ao misturar streams stdout e stderr) é que há dependência dos streams sendo liberados pelo programa. Se, por exemplo, todas as gravações no stdout não forem liberadas, mas todas as gravações no stderr forem liberadas, elas terminarão fora da ordem cronológica no arquivo de saída e na canvas.

Também é ruim se o programa só gera 1 ou 2 linhas a cada poucos minutos para relatar o progresso. Nesse caso, se a saída não fosse liberada pelo programa, o usuário nem mesmo veria qualquer saída na canvas por horas, porque nada disso seria empurrado pelo tubo por horas.

Atualização: O unbuffer programa, parte do pacote expect , resolverá o problema de buffering. Isso fará com que stdout e stderr escrevam na canvas e arquivem imediatamente e os mantenha em sincronia quando forem combinados e redirecionados para tee . Por exemplo:

 $ unbuffer program [arguments...] 2>&1 | tee outfile 

Outra maneira que funciona para mim é,

  |& tee  

como mostrado no manual do gnu bash

Exemplo:

 ls |& tee files.txt 

Se ‘| &’ for usado, o erro padrão do comando 1, além de sua saída padrão , é conectado à input padrão do comando2 através do tubo; é uma abreviatura de 2> & 1 | Esse redirecionamento implícito do erro padrão para a saída padrão é executado após qualquer redirecionamento especificado pelo comando.

Para mais informações, consulte redirecionamento

Você pode usar principalmente a solução Zoredache , mas se você não quiser sobrescrever o arquivo de saída, você deve escrever tee com a opção -a da seguinte forma:

 ls -lR / | tee -a output.file 

Algo para adicionar …

O pacote unbuffer tem problemas de suporte com alguns pacotes sob o fedora e redhat unix.

Deixando de lado os problemas

A seguir funcionou para mim

 bash myscript.sh 2>&1 | tee output.log 

Obrigado ScDF & matthew seus insumos me poupou muito tempo ..

usando tail -f output deve funcionar.

Resposta de bônus desde que este caso de uso me trouxe aqui:

No caso em que você precisa fazer isso como algum outro usuário

 echo "some output" | sudo -u some_user tee /some/path/some_file 

Note que o eco irá acontecer como você e o arquivo irá acontecer como “some_user” o que NÃO irá funcionar se você rodar o echo como “some_user” e redirect a saída com >> “some_file” porque o redirecionamento do arquivo irá acontecer como você.

Dica: tee também suporta append com o sinalizador -a, se você precisar replace uma linha em um arquivo como outro usuário, você pode executar sed como o usuário desejado.

< command > |& tee filename # isto criará um arquivo “filename” com status de comando como conteúdo. Se um arquivo já existir, ele removerá o conteúdo existente e gravará o status do comando.

< command > | tee >> filename < command > | tee >> filename # isso appendá o status ao arquivo, mas não imprimirá o status do comando na saída_de_example (canvas).

Eu quero imprimir algo usando “echo” na canvas e acrescentar que os dados ecoaram em um arquivo

 echo "hi there, Have to print this on screen and append to a file" 

tee é perfeito para isso, mas isso também fará o trabalho

 ls -lr / > output | cat output