Usando o bash, como copio stderr e stdout para um arquivo de log e também os deixo exibidos no console?
Eu gostaria de fazer isso dentro do próprio script usando um exec.
Eu tentei com
exec &>> log.out
echo "This is stdout"
echo "This is stderr" >&2
Mas o acima exposto não imprime nada no console. Como posso conseguir isso no bash?
Respostas:
Você está procurando
tee
.Veja
man tee
para detalhes.Para combiná-lo
exec
, é necessário usar a substituição de processo . (Vejaman bash
para detalhes.)fonte
exec 2>&1 | tee -a log.out
apenas impressões no console, nada no arquivo de log. Talvez eu não esteja usando a sintaxe correta?tee
em combinação com a substituição do processo .the-script | wc -l
, isso também contará as linhas de erro e você não verá os erros.Você pode fazer:
Você também pode escrever como:
Mas como o bash não aguarda os processos iniciados com
>(...
), isso tem o efeito desagradável de, às vezes, gerar algo para o terminal após o retorno do comando, que pode ter efeitos ainda mais desagradáveis (como descartar silenciosamente essa saída) se o atributo "tostop" do terminal está ligado.De qualquer forma, criando
stdout
um canal nas duas soluções e como dois comandos emitem independentemente as mensagens de saída e erro, isso afetará o buffer de saída e a ordem em que as mensagens de saída e erro serão exibidas.fonte
tee -a log >&2 3>&-
Eu sei que este é um post antigo, mas por que não fazer isso?
E, claro, se você quiser o stdout, poderá imprimir regularmente.
Você pode fazer isso com qualquer combinação de fluxos que desejar, apenas usando esses dois comandos básicos.
Sei que vim para cá e não obtive uma resposta fácil de entender / implementar, espero que isso ajude alguém que esteja com dificuldades.
A propósito, para noobs por aí como o meu eu anterior, tudo o que o
tee
comando faz é gerar a entrada stdin para o stdout e os arquivos especificados como argumentos subsequentes.-a
significa acréscimo, para que você não sobrescreva o arquivo a cada uso do comando. Se você tiver mais perguntas, considero este um recurso muito útil para aprender rapidamente o bash.fonte
Mais uma maneira de fazer isso é usar redirecionamentos nas funções.
Aqui temos uma
main
função que chama todas as outras funções. Agora redirecionandoSTDOUT
eSTDERR
demain
função paratee
.fonte