Como posso registrar completamente todas as ações de scripts bash?

44

Quero capturar TODOS os dados dos logs, ambos com mensagens de erro, da saída do meu script e redirecioná-los todos para o arquivo de log.

Eu tenho script como abaixo:

#!/bin/bash
(
echo " `date` : part 1 - start "
ssh -f admin@server.com 'bash /www/htdocs/server.com/scripts/part1.sh logout exit'
echo " `date` : sleep 120"
sleep 120
echo " `date` : part 2 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part2.sh logout exit'
echo " `date` : part 3 - start"
ssh admin@server.com '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 vejo apenas isso o que coloquei após o comando echo.

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

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

BlueMark
fonte
Você também pode usar o "script" para fazer isso. Veja esta publicação: [aqui] [1] [1]: stackoverflow.com/questions/5985060/…
xX0v0Xx
você deve ter cuidado com o errexit - notei que ele é ignorado ou o erro não sai do script, por exemplo. se você tiver algo parecido com isto no script: command || dosmthg quando comando falhar script não sair imediatamente com o conjunto errexit mas apenas executar dosmthg e continua o script

Respostas:

67

Geralmente, coloco algo semelhante ao seguinte no início de cada script (especialmente se 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 arquivo para que possam ser restaurados para o que eram antes do redirecionamento ou usados ​​para gerar a saída para o que eram antes do redirecionamento a seguir.

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

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

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

    Redirecione stdoutpara o arquivo e log.outdepois redirecione stderrpara stdout. Observe que o pedido é importante quando você deseja que eles acessem o mesmo arquivo. stdout deve ser redirecionado antes de stderrser 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 quer que tenha stdoutsido direcionado, presumivelmente para o console, antes de executar a linha 3 acima.

nicerobot
fonte
<< niceroot, Obrigado! Eu adicionei esses threelines (exec, trap, exec) no início do script e posso obter stdout e stderr. Mas um problema: eu vi "O descritor de arquivo 3 (canal: XXX) vazou em algum comando" ... Por favor, deixe-me saber como posso evitar esses erros. Eu estou usando o sh do busybox no quadro personalizado.
kumar
3
Grande KungFu aqui !!! - Melhor ainda é usar trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. Os pseudo-sigspec RETURN restauram descritores de arquivo sempre que uma função shell ou um script é executado com o. ou a fonte builtins termina a execução. Por isso (e por outras razões) em meus scripts, adiciono as duas últimas linhas: return& exit 0- Apenas meus 2 centavos, parabéns a você @nicerobot!
21415 DavAlPi
Há uma boa quantidade de detalhes no registro de scripts de shell por meio de variáveis ​​globais do shell. Podemos imitar o tipo semelhante de registro no script de shell: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html A postagem possui detalhes sobre a introdução de níveis de log como INFO, DEBUG, ERROR. Detalhes de rastreamento, como entrada de script, saída de script, entrada de função, saída de função.
Piyush Chordia
A enumeração de trapsinais parece um pouco estranha. Normalmente você também vai querer incluir 15.
tripleee
1
@PiyushChordia ligação correção: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html
vigilancer
14

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

deve ficar assim:

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

quando isso não exibir as mensagens na ordem correta, tente adicionar outro subshell:

#!/bin/bash
((
...
) 2>&1) | tee ...
cristão
fonte
1
Isso funciona muito bem. Na verdade, você pode direcionar stdout e stderr com:( ... ) |& tee output.log
Noam Manos
13

Enquanto eu leio 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 produzir tudo:

sh -x foo.sh

Faça logon no arquivo que você deseja:

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

Alex Holst
fonte
2
Opção +1 para -x
Coc
10

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

Se você quer ser paranóico, pode inserir set -o errexitseu script. Isso significa que o script falhará e será interrompido se um comando retornar um código de saída diferente de zero, que é a maneira padrão do unix de sinalizar que algo deu errado.

Se você deseja obter logs mais agradáveis, consulte tso moreutilspacote debian / ubuntu. Ele irá prefixar cada linha com um carimbo de data e hora e imprimi-lo. Então você pode ver quando as coisas estavam acontecendo.

Rory
fonte
1
"set -o errexit" deve ser a mesma coisa que "set -e"
Ajith Antony
0

Seguindo o que outros disseram, o manual do conjunto é um bom recurso. Eu coloco:

#!/usr/bin/env bash
exec 1> command.log 2>&1
set -x

Na parte superior dos scripts, desejo continuar, ou set -exse ele sair após erro.

dragon951
fonte
Como isso ajudará os logs ssh e a execução bem-sucedida do comando?
asktyagi
Testando com o script fictício do OP, ele registra cada comando e qualquer que seja o resultado: tempo limite do ssh, domínio incorreto etc. Ou, para um endereço ssh válido, registra os comandos no shell remoto. Se mais informações sobre logins ssh forem necessárias, talvez ssh -vv?
dragon951 3/06