É assim que registro stdout e stderr em meus scripts (geralmente cronjobs):
#!/bin/bash
mylog() {
echo "[`date '+%Y-%m-%d %H:%M:%S'`] $1"
}
(
mylog 'start'
some-command || mylog 'error' && exit 1
mylog 'end'
) >> /var/log/my-log.log 2>&1
Em alguns scripts eu uso return em vez de exit e funciona bem, mas agora diz que não posso usar return a menos que inclua o script com src ou use-o em uma função. Então mudei para sair, mas o problema é que ele não registra nada, parece que interrompe o redirecionamento de saída >>. Outro problema é que não poderei incluí-lo posteriormente com o src, pois só quero parar esse script, não tudo.
Eu uso o redirecionamento de saída porque quero registrar tudo, mesmo que nenhum erro tenha ocorrido. E às vezes os comandos nem retornam códigos de saída adequados, então não posso confiar nisso.
Então, como posso 'retornar' em caso de erro? Conheço 'set -e', mas prefiro ter mais controle sobre quando parar o script.
Alguma ideia?
Responder1
Não consigo explicar o comportamento que você está enfrentando, mas aqui está uma solução possível:
#!/bin/bash meulog() { echo "[$(data '+%Y-%m-%d %H:%M:%S')] $1" } meu principal() { ( meulog 'iniciar' algum comando || mylog 'erro' && retorno 1 meulog 'fim' ) >> /var/log/my-log.log 2>&1 } meu principal
Como alternativa, remova o redirecionamento da mymain
definição da função e coloque-o na mymain
chamada da função:
mymain >> /var/log/my-log.log 2>&1
(Você também deve ser capaz de excluir os parênteses da mymain
definição da função.) Alternativamente, como você deseja que o IO seja redirecionado para ointeiroscript, você pode separar o redirecionamento das instruções de ação:
exec >> /var/log/my-log.log executivo 2>&1 meu principal
Como não entendo por que sua abordagem está falhando, não posso explicar por que qualquer uma das opções acima tem maior probabilidade de funcionar conforme desejado. No entanto, são maneiras ligeiramente diferentes de fazer a mesma coisa e isso pode ser suficiente. A propósito, mudei `date …`
para $(date …)
apenas por motivos gerais; Não acredito que isso tenha algo a ver com o seu problema.
Responder2
Que tal usar o screen
comando no Linux? Isso seria um truque, a menos que você esteja decidido a programar uma solução sozinho.