No bash, a chamada foo
exibia qualquer saída desse comando no stdout.
A chamada foo > output
redirecionaria qualquer saída desse comando para o arquivo especificado (neste caso, 'saída').
Existe uma maneira de redirecionar a saída para um arquivo e exibi-la no stdout?
foo > output
os dados, ele é gravado em stdout e stdout é o arquivo nomeadooutput
. Ou seja, gravar no arquivo está gravando no stdout. Você está perguntando se é possível escrever no stdout e no terminal.Respostas:
O comando que você deseja é nomeado
tee
:Por exemplo, se você se importa apenas com stdout:
Se você deseja incluir o stderr, faça:
2>&1
redireciona o canal 2 (erro padrão / stderr) para o canal 1 (saída padrão / padrão), de modo que ambos sejam gravados como padrão. Também é direcionado para o arquivo de saída fornecido, a partir dotee
comandoAlém disso, se você deseja anexar ao arquivo de log, use
tee -a
como:fonte
-a
argumentotee
para o conteúdo acréscimo paraoutput.file
, em vez de substituí-lo:ls -lR / | tee -a output.file
$?
posteriormente, ele retornará o código de status detee
, que provavelmente não é o que você deseja. Em vez disso, você pode usar${PIPESTATUS[0]}
.2>&1
despeja os fluxos stderr e stdout.tee outfile
pega o fluxo que obtém e grava na tela e no arquivo "outfile".Provavelmente é isso que a maioria das pessoas está procurando. A situação provável é que algum programa ou script esteja trabalhando duro por um longo tempo e produzindo muita saída. O usuário deseja verificar periodicamente o progresso, mas também deseja que a saída seja gravada em um arquivo.
O problema (especialmente ao misturar fluxos stdout e stderr) é que existe confiança nos fluxos 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 acabarão fora de ordem cronológica no arquivo de saída e na tela.
Também é ruim se o programa emitir apenas 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 veria nenhuma saída na tela por horas, porque nada disso seria empurrado pelo cano por horas.
Atualização: O programa
unbuffer
, parte doexpect
pacote, resolverá o problema do buffer. Isso fará com que stdout e stderr gravem na tela e no arquivo imediatamente e os mantenham sincronizados ao serem combinados e redirecionados paratee
. Por exemplo:fonte
$ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile
python
possui uma opção integrada-u
que impede a saída de buffer.Outra maneira que funciona para mim é,
como mostrado no manual do gnu bash
Exemplo:
Para mais informações, consulte redirecionamento
fonte
$?
posteriormente, ele retornará o código de status detee
, que provavelmente não é o que você deseja. Em vez disso, você pode usar${PIPESTATUS[0]}
.Você pode usar principalmente a solução Zoredache , mas se não quiser sobrescrever o arquivo de saída, deve escrever tee com a opção -a da seguinte maneira:
fonte
Algo a acrescentar ...
O unbuffer de pacote possui problemas de suporte em alguns pacotes sob as versões fedora e redhat unix.
Deixando de lado os problemas
Seguindo trabalhou para mim
fonte
Usar
tail -f output
deve funcionar.fonte
Resposta bônus, pois esse caso de uso me trouxe aqui:
No caso em que você precisa fazer isso como outro usuário
Observe que o eco acontecerá enquanto você e a gravação do arquivo ocorrerão como "some_user", o que NÃO funcionará é se você executasse o eco como "some_user" e redirecionasse a saída com >> "some_file" porque o redirecionamento do arquivo ocorrerá como você.
Dica: tee também suporta anexar com o sinalizador -a, se você precisar substituir uma linha em um arquivo como outro usuário, poderá executar sed como o usuário desejado.
fonte
< command > |& tee filename
# isto criará um arquivo "filename" com o status do comando como um conteúdo. Se um arquivo já existir, ele removerá o conteúdo existente e gravará o status do comando.< command > | tee >> filename
# isto acrescentará status ao arquivo, mas não imprimirá o status do comando em standard_output (tela).Quero imprimir algo usando "eco" na tela e anexar esses dados a um arquivo
fonte
Você pode fazer isso em todo o script usando algo assim no início do script:
Isso redireciona as saídas stderr e stdout para o arquivo chamado
mylogfile
e permite que tudo vá para o stdout ao mesmo tempo .São utilizados alguns truques estúpidos:
exec
sem comando para configurar redirecionamentos,tee
para duplicar saídas,NUL
caractere simples especificado pela$'string'
notação especial do bash) para especificar que o script será reiniciado (nenhum parâmetro equivalente pode ser usado pelo seu trabalho original),pipefail
opçãoFeio, mas útil para mim em certas situações.
fonte
tee é perfeito para isso, mas isso também fará o trabalho
fonte
;
, a saída seria muito atrasada durante um comando lento.