bash: configura -x logs para arquivo


18

Eu tenho um script de shell com set -xa saída detalhada / depuração:

#!/bin/bash

set -x
command1
command2
...

A saída é assim:

+ command1
whatever output from command1
+ command2
whatever output from command2

Meu problema é, a saída de shell (causada por set -x) vai para o stderr, misturado com a saída dos comandos ( command1, command2...). Eu ficaria feliz em ter a saída "normal" na tela (como o script sem o woud set -x) e a saída "extra" do bash separadamente em um arquivo.

Então, eu gostaria de ter isso na tela:

whatever output from command1
whatever output from command2

e isso em um arquivo de log:

+ command1
+ command2

(também é bom se o arquivo de log tiver tudo junto)

O set -x 2> fileobviamente doens't ter o efeito certo, porque não é a saída do comando set, mas mudar o comportamento do bash.

Usar bash 2> fileo script inteiro também não faz a coisa certa, porque redireciona o stderr de todos os comandos que são executados neste shell, portanto, não vejo a mensagem de erro dos comandos.


Respostas:


20

Com base nesta resposta ServerFault Envie a saída bash -x para o arquivo de log sem interromper a saída padrão , as versões modernas do bash incluem um BASH_XTRACEFDespecífico para especificar um descritor de arquivo alternativo para a saída deset -x

Então, por exemplo, você pode fazer

#!/bin/bash

exec 19>logfile
BASH_XTRACEFD=19

set -x
command1
command2
...

para enviar a saída set -xpara o arquivo logfile, preservando a saída padrão regular e os fluxos de erro padrão para os seguintes comandos.

Observe que o uso do fd 19 é arbitrário - ele só precisa ser um descritor disponível (ou seja, não 0, 1, 2 ou outro número que você já alocou).


Na verdade, ele salva o log de rastreamento do bash separadamente, no entanto, torna muito difícil ler as 2 saídas (stdout + stderr na tela e o rastreamento do bash nos arquivos de log), pois ficam completamente fora de sincronia. Veja a solução que acabei de postar .
precisa saber é

4

Depois de mais de um ano, encontrei a solução certa para exibir a saída "normal" (stdout + stderr - bash trace) na tela e todos juntos (stdout + stderr + bash trace) em um arquivo (bash.log) :

exec   > >(tee -ia bash.log)
exec  2> >(tee -ia bash.log >& 2)
exec 19> bash.log

export BASH_XTRACEFD="19"
set -x

command1
command2

Essa é apenas a combinação da resposta da chave de aço e esta .
jarno 27/10

3

A Steeldriver ofereceu uma abordagem. Como alternativa, você pode simplesmente redirecionar o STDERR para um arquivo:

script.sh 2> logfile

Isso, no entanto, significa que a saída criada pela set -xopção e quaisquer outras mensagens de erro produzidas irão para o arquivo. A solução da Steeldriver redirecionará apenas a set -xsaída que provavelmente é o que você deseja.


"... tanto a saída criada pela opção set -x quanto qualquer outra mensagem de erro produzida irá para o arquivo." E é por isso que não funciona para mim. Meu problema principal é que não vejo "erros reais" facilmente, porque toda essa saída do bash vai para o stderr. Redirecionar as mensagens de erro dos comandos também me ocultaria os "erros reais" de uma maneira diferente.
redseven

@redseven Acho que o que você está pedindo não está muito claro então. Você pode editar sua pergunta e esclarecer? Tente evitar o uso do termo "output" para qualquer coisa que não seja stdout. Deseja separar i) saída normal; ii) algum erro gerado por seu comando e iii) set -x? A resposta da chave de aço não é suficiente? Caso contrário, mostre-nos um script simples que possamos copiar e diga como você deseja que ele se comporte.
terdon 25/10/16

@steeldriver já respondeu perfeitamente à pergunta.
redseven

@redseven ah, legal então. Desde que seu comentário foi publicado mais tarde, achei que você ainda precisava de algo e não conseguia ver como a resposta da chave de aço falhou na solução do seu problema. Ainda bem que está tudo resolvido então.
terdon 28/10
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.