Como redirecionar stderr e stdout para arquivos diferentes e também exibir no terminal?

30

Eu quero ver a saída de um comando no terminal como se não houvesse redirecionamento. Além disso, o stderr precisa ser redirecionado para err.log e o stdout precisa ser redirecionado para o stdout.log.

Seria bom também ter a cópia exata do que é mostrado no terminal, ou seja, erros impressos como e quando ocorrem, em um arquivo separado: stdouterr.log.

balki
fonte
@Nuno Não, não é. O OP quer ter arquivos diferentes para stdout e stderr.
25411 dogbane
@dogbane Sim, você está certo. Me desculpe por isso.
Nuno C. Inácio
Ainda acho essa pergunta muito familiar. Deixe-me olhar para cima ... Aqui é muito semelhante unix.stackexchange.com/q/4195/250 , e aqui está uma relacionada um unix.stackexchange.com/q/1416/250
phunehehe

Respostas:

37

Use o teecomando da seguinte maneira:

(cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log

3>&1 1>&2 2>&3 é assim que você troca stderr e stdout, porque tee só pode aceitar stdout.

Dê uma olhada no comando tee do Unix para redirecionamentos mais avançados usando tee.

dogbane
fonte
boa solução. Existe alguma maneira de obter o código de saída do cmd?
turbanoff
2
@turbanoff Substitua cmdpor (cmd ; echo >exit_code.txt $?).
Tiro parta
Eu acredito que isso deve preservar melhor a ordem das coisas exibidas na linha de comando:((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log)
TTT
5

Acho que registrar stdout e stderr em dois arquivos diferentes é uma ideia esplêndida. Não torna os logs assíncronos? Então, tentei o seguinte:

  • stdout para "stdout.log" (como dogbane sugeriu)
  • stderror para "stderr.log" (como dogbane sugeriu)
  • toda a saída para "all.log" e
  • ainda será capaz de ver a saída no visor (em um terminal separado!)

((cmd | tee stdout.log) 3>&1 1>&2 2>&3 | tee stderr.log) &> all.log

em outro terminal

tail -f --sleep-interval=2 all.log
Sreeni
fonte
Não é possível direcionar o stderr diretamente para um segundo tty? Então, nenhum arquivo de log é necessário.
9609 Steven
@StevenLu sim, se você souber o nome e tiver permissão para escrever no segundo tty que pode ser feito.
Jasen
11
mais fácil seria &| tee all.logno final do comando em vez de&> all.log
Jasen
@ Jasen: segunda vez que vejo &|. Eu também entendo &>, |&mas o que &|significa nesse contexto? Não consegui encontrar uma referência de sintaxe adequada, nem na rede, nem mesmo consultando a página de manual do bash "bash (1)" ... Tx
Cbhihe 07/02/16
11
@Cbhihe, tanto quanto eu posso dizer que não faz nada, eu quis dizer|&
Jasen
3

@dogbane, Obrigado.
Também encontrei outra maneira que salva os fluxos aproximadamente na ordem em que seriam impressos sem redirecionamento.

command 2> >(tee errlog | tee -a bothLog > /dev/tty ) | tee outlog | tee -a bothLog

Mas isso funciona apenas com os shells que suportam a substituição do processo.

balki
fonte
-2

tente isto:

command 2>&1 | tee bothLog
vasile
fonte
4
Olá vasile, isso não responde à pergunta: balki precisa de arquivos separados para stdout e stderr, sua solução misturaria os dois no mesmo fluxo.
Mat
Por que as pessoas mesclam stdout e stderr juntos? Ou dizer aos outros para fazê-lo?
Nurettin