Como posso registrar totalmente todas as ações dos scripts bash?

35

Eu quero capturar TODOS os dados de registros, ambos com mensagens de erro, da saída do meu script e redirecioná-los para o arquivo de log.

Eu tenho um script como abaixo:

#!/bin/bash
(
echo " 'date' : part 1 - start "
ssh -f [email protected] 'bash /www/htdocs/server.com/scripts/part1.sh logout exit'
echo " 'date' : sleep 120"
sleep 120
echo " 'date' : part 2 - start"
ssh [email protected] 'bash /www/htdocs/server.com/scripts/part2.sh logout exit'
echo " 'date' : part 3 - start"
ssh [email protected] 'bash /www/htdocs/server.com/scripts/part3.sh logout exit'
echo " 'date' : END"
) | tee -a /home/scripts/cron/logs

Eu quero ver todas as ações no arquivo /home/scripts/cron/logs

Mas eu vejo apenas isso que eu coloquei após o comando echo.

Como fazer o check-in dos logs, o comando SSH foi bem-sucedido?

Eu preciso reunir todos os dados dos registros. Eu preciso disso para monitorar o resultado de cada comando no meu script, para analisar melhor o que está acontecendo enquanto o script falha.

    
por BlueMark 17.01.2010 / 12:17

4 respostas

53

Eu geralmente coloco algo semelhante ao seguinte no início de cada script (especialmente se ele for executado como um daemon):

#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
# Everything below will go to the file 'log.out':

Explicação:

  1. exec 3>&1 4>&2

    Salva os descritores de arquivos para que eles possam ser restaurados para o que quer que fossem antes do redirecionamento ou utilizados para gerar a saída para o que quer que fosse antes do redirecionamento a seguir.

  2. trap 'exec 2>&4 1>&3' 0 1 2 3

    Restaurar descritores de arquivo para sinais específicos. Geralmente não é necessário, pois eles devem ser restaurados quando a sub-shell sair.

  3. exec 1>log.out 2>&1

    Redirecione stdout para o arquivo log.out e, em seguida, redirecione stderr para stdout . Observe que a ordem é importante quando você quer que eles acessem o mesmo arquivo. stdout deve ser redirecionado antes que stderr seja redirecionado para stdout .

A partir de então, para ver a saída no console (talvez), você pode simplesmente redirecionar para &3 . Por exemplo,

echo "$(date) : part 1 - start" >&3

irá para onde stdout foi direcionado, presumivelmente o console, antes de executar a linha 3 acima.

    
por 17.01.2010 / 18:54
12

para obter a saída ssh para seu arquivo de log, você deve redirecionar stderr para stdout . você pode fazer isso adicionando 2>&1 após o seu script bash.

deve ficar assim:

#!/bin/bash
(
...
) 2>&1 | tee ...

quando isso não exibir as mensagens na ordem correta, tente adicionar outra sub-lista:

#!/bin/bash
((
...
) 2>&1) | tee ...
    
por 17.01.2010 / 13:24
11

Ao ler sua pergunta, você não deseja registrar a saída, mas toda a sequência de comandos, nesse caso, as outras respostas não o ajudarão.

Invoque scripts de shell com -x para gerar saída de tudo:

sh -x foo.sh

Faça o login no arquivo desejado:

sh -x foo.sh >> /home/scripts/cron/logs

    
por 17.01.2010 / 19:02
10

No bash, você pode colocar set -x e imprimir todos os comandos que ele executa (e as variáveis bash) depois disso. Você pode desativá-lo com set +x .

Se você quiser ser paranóico, pode colocar set -o errexit no seu script. Isso significa que o script falhará e parará se um comando retornou um código de saída diferente de zero, que é a maneira padrão unix de sinalizar que algo deu errado.

Se você deseja obter registros mais agradáveis, deve olhar para ts no pacote moreutils debian / ubuntu. Ele irá prefixar cada linha com um timestamp e imprimi-lo. Então você pode ver quando as coisas estavam acontecendo.

    
por 25.01.2010 / 12:38