Cron: Recebe apenas erros nos emails?

39

Finalmente, configurei um agendamento de backup realista dos meus dados por meio de um script de shell, que são tratados pelo cron em intervalos apertados. Infelizmente, continuo recebendo e-mails vazios toda vez que o CRON é executado e não apenas quando as coisas dão errado.

É possível fazer apenas o CRON enviar e-mails quando algo der errado, ou seja. my TARnão executa como pretendido?

Veja como meu crontab está configurado para o momento;

0 */2 * * * /bin/backup.sh 2>&1 | mail -s "Backup status" email@example.com

Muito obrigado!

Industrial
fonte

Respostas:

54

Idealmente, você deseja que seu script de backup não produza nada se tudo correr como esperado e só produzirá saída quando algo der errado. Em seguida, use a variável de ambiente MAILTO para enviar qualquer saída gerada pelo seu script para o seu endereço de email.

MAILTO=email@example.com
0 */2 * * * /bin/backup.sh

Se seu script normalmente produz saída, mas você não se importa com isso no cron, envie-o para / dev / null e ele enviará um e-mail apenas quando algo estiver escrito no stderr.

MAILTO=email@example.com
0 */2 * * * /bin/backup.sh > /dev/null
Cakemox
fonte
9
Isso dificilmente é ideal. Você geralmente deseja que a saída inteira (stdout + stderr) seja enviada por e-mail quando o comando terminar com um código de erro diferente de zero. Caso contrário, geralmente é bom devorar pelo menos stdout. Para mim, essa é uma falha de design do cron.
Witiko
3
@Witiko eu concordo; Eu encontrei esta pergunta tentando consertar isso. Eu acho que você pode fazer o seu comando cron /bin/backup.sh > log_file || (echo Backup failed with exit status $?; cat log_file)?
Daniel H
22

Usar script de wrapper crônico parece uma boa idéia; Para usá-lo, você não precisa alterar seus scripts.

Ao invés de:

 0 1 * * * /bin/backup.sh 2>&1 | mail -s "Backup status" email@example.com

Faz:

 MAILTO=email@example.com
 0 1 * * * cronic /bin/backup.sh

Basta colocar; ele funcionará silenciosamente se tudo funcionar sem problemas (status de saída 0), mas será reportado detalhadamente, se não, e permitirá que o cron lide com os relatórios de email.

Mais informações em https://habilis.net/cronic/ .

Ricardo Pardini
fonte
Realmente não vejo como isso vai ajudar quando o problema não passa de uma linha cron incorreta e o cron está fazendo exatamente o que é solicitado.
John Gardeniers
3
@JohnGardeniers ajuda porque às vezes você produz resultados sem erros.
Mikhail
11
Como alternativa, chronicdo moreutilspacote: joeyh.name/code/moreutils
Vladimir Panteleev
4

Você está instruindo especificamente cronpara sempre enviar e-mail, mesmo quando /bin/backup.sh(a propósito, ele deve /usr/local/binaparecer) for bem-sucedido. Apenas omita a | mail -s "Backup status" [email protected]parte e o email será enviado somente quando houver saída. Provavelmente (dependendo do seu cron), você pode definir explicitamente o endereço de e-mail como e-mail como uma atribuição no arquivo crontab.

Para detalhes, consulte

man 5 crontab
reinierpost
fonte
3

Você deve direcionar o stderranmd e não ambos stdoute stderr.

1> /dev/nullNão use 2>&1e deve ficar bem. Além disso, pode ser necessário relatar o erro corretamente no seu script de backup.

Khaled
fonte
3

Aqui está outra variação que utilizei com sucesso por muitos anos - capture a saída e a imprima apenas por erro , acionando um email. Isso não requer arquivos temporários e preserva toda a saída . A parte importante é a 2>&1que redireciona STDERR para STDOUT.

Envie a saída inteira via configuração padrão do cron mailer:

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT"

O mesmo, mas com um endereço e assunto específicos:

(o endereço também pode ser alterado definindo MAILTO = xxxx para todo o arquivo crontab)

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT" | mail -s "Failed to backup" an@email.address

Você pode até executar várias ações com erro e adicionar ao email:

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || {echo "$OUTPUT" ; ls -ltr /backup/dir ; }

Isso funcionará para comandos simples. Se você estiver lidando com pipes complexos ( find / -type f | grep -v bla | tar something-or-other), é melhor mover o comando para um script e executar o script usando a abordagem mencionada acima. O motivo é que, se alguma parte do tubo for enviada para STDERR, você ainda receberá e-mails.

Akom
fonte