Como redirecionar a saída e sair na falha do comando?

1

É assim que eu faço o log de stdout e stderr nos 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 ele diz que não posso usar return a menos que eu inclua o script com src ou use-o em uma função. Então eu mudei para sair, mas o problema é que ele não registra nada, parece que ele pára o > > redirecionamento de saída. Outro problema é que eu não poderei incluí-lo mais tarde com src, porque eu só quero parar este 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 apropriados, então não posso confiar nisso.

Então, como posso "retornar" ao erro? Eu sei sobre 'set -e', mas eu prefiro ter mais controle sobre quando parar o script.

Alguma opinião?

    
por ChocoDeveloper 31.12.2012 / 00:14

2 respostas

1

Não consigo explicar o comportamento que você está enfrentando, mas aqui está uma possível correção:

#!/bin/bash
mylog() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}

mymain() {
    (
        mylog 'start'

        some-command  ||  mylog 'error'  &&  return 1

        mylog 'end'
    ) >> /var/log/my-log.log 2>&1
}

mymain

Como alternativa, remova o redirecionamento da definição da função mymain e coloque-o na chamada de função mymain :

mymain >> /var/log/my-log.log 2>&1

(Você também deve excluir os parênteses da definição da função mymain .) Como alternativa, como você deseja que o E / S seja redirecionado para o script inteiro , pode interromper o redirecionamento além das declarações de ação:

exec >> /var/log/my-log.log
exec 2>&1
mymain

Como não entendo por que sua abordagem está falhando, não consigo explicar por que é mais provável que qualquer um dos itens acima funcione conforme desejado. No entanto, são maneiras ligeiramente diferentes de fazer a mesma coisa, e isso pode ser suficiente. By the way, eu mudei 'date …' para $(date …) apenas por razões gerais; Eu não acredito que tenha algo a ver com o seu problema.

    
por 31.12.2012 / 22:58
0

Que tal usar o comando screen no linux? Isso seria devido ao truque, a menos que você tenha coragem de programar uma solução sozinho.

    
por 31.12.2012 / 05:47

Tags