Cron: somente envia um e-mail se a saída contiver uma string

1

Posso fazer com que o cron envie apenas o email se a saída ( stderr ) contiver uma determinada string?

Estou ciente de esta resposta , mas o comando que eu executo não é possível distinguir entre stdout / stderr , é sempre apenas saídas para stdout , então eu preciso procurar por uma string.

Até agora eu tenho isso e basicamente funciona, exceto que o grep não passa a saída para o comando mail, então eu só recebo um email vazio:

0 5 * * * root mycommand | grep -q 'Renewal was done' && mail -s 'Renewal completed' [email protected]

Como posso obter a saída inteira do mycommand incluída no email?

    
por TheStoryCoder 17.02.2017 / 13:02

3 respostas

2

Eu sugiro que você coloque a lógica em um script e execute esse script no cron em vez de tentar criar um script de liner no cron. Dessa forma, você pode testá-lo facilmente fora do cron, por exemplo:

#!/bin.bash
tmp=/tmp/t$$
mycommand > $tmp 
if grep -q 'Renewal was done' $tmp
then
    mail -s 'Renewal completed' [email protected] < $tmp
fi

rm -f $tmp
exit 0

Você pode adicionar a verificação do status de saída mycommand, passar o comando que está sendo executado, a string que está sendo correspondida e o endereço de e-mail como parâmetros etc.

    
por 17.02.2017 / 13:43
1

Isso pode funcionar.

#!/bin/sh
COMMAND='mycommand'
FINDSTR="renewal was done"

ANSWER = '$COMMAND | grep $FINDSTR' 

if $ANSWER; then
  echo $ANSWER > mail -s 'Renewal Completed' [email protected]
fi
    
por 17.02.2017 / 13:27
0

Veja como eu faço:

Neste cenário eu tenho 4 bancos de dados (dumps) que eu preciso fazer backup e se tudo deu certo eu quero receber um e-mail mencionando isso. Se eu tiver erros, quero que uma mensagem com um assunto diferente aponte para fora, o banco de dados com falha incluído no corpo da mensagem e o log de erros anexado ao email.

O primeiro arquivo ( /root/templates/ylatis-backup.txt ) é apenas um modelo de corpo da mensagem:

Backup status report from: %hostname

Network configuration:
%net_config

Database backups:
ylatis-cy :%cy_status
ylatis-ug :%ug_status
ylatis-rw :%rw_status
ylatis-lc :%lc_status

Todas as palavras prefixadas por% são tratadas como variáveis e substituídas por sed mais tarde no script.
% hostname e% net_config são usados para identificar de qual computador o email está vindo.
As variáveis que terminam em _status são substituídas pela palavra NORMAL ou ERROR para que eu possa saber o que deu errado.

#!/bin/bash

NET_CONFIG=$(ifconfig |grep inet |grep -v inet6 |grep -v '127.0.0.1')
MESSAGE_TEMPLATE=/root/templates/ylatis-backup.txt
REPORT_FILE=/tmp/bkup-report-$$.txt
MESSAGE=$(cat $MESSAGE_TEMPLATE)

MAIL_FROM='[email protected]'
MAIL_TO='[email protected]'
MAIL_SUBJECT="[$HOSTNAME] [Backup Report: Databases] %status  [$(date +%Y-%m-%d)]"
MAIL_SERVER='smtp.gmail.com:587'
MAIL_USER='[email protected]'
MAIL_PASS='**********'

CY_ERR=/tmp/ylatis-cy_err.$$
UG_ERR=/tmp/ylatis-ug_err.$$
RW_ERR=/tmp/ylatis-rw_err.$$
LC_ERR=/tmp/ylatis-lc_err.$$

ERROR_LOG=/tmp/error_log-$$.txt

MESSAGE=$(echo "$MESSAGE" |sed 's@%hostname@'"$HOSTNAME"'@g')
MESSAGE=$(echo "$MESSAGE" |sed 's@%net_config@'"$NET_CONFIG"'@g')

mount -a
rsync -azv --chown root:root [email protected]::backup/ /mnt/hdd3/ylatis-cy/ 1>/dev/null 2>$CY_ERR
cy_status=$?
rsync -azv --chown root:root [email protected]::ylatisug/ /mnt/hdd3/ylatis-ug/ 1>/dev/null 2>$UG_ERR
ug_status=$?
rsync -azv --chown root:root [email protected]::ylatisrw/ /mnt/hdd3/ylatis-rw/ 1>/dev/null 2>$RW_ERR
rw_status=$?
rsync -azv --chown root:root [email protected]::labco/ /mnt/hdd3/ylatis-labco/ 1>/dev/null 2>$LC_ERR
lc_status=$?

if [ $cy_status -eq 0 ] && [ $ug_status -eq 0 ] && [ $rw_status -eq 0 ] && [ $lc_status -eq 0 ]; then
##########
#ALL GOOD#
##########

MAIL_SUBJECT=$(echo "$MAIL_SUBJECT" |sed 's@%status@[NORMAL]@g')

MESSAGE=$(echo "$MESSAGE" |sed 's@%cy_status@NORMAL@g')
MESSAGE=$(echo "$MESSAGE" |sed 's@%ug_status@NORMAL@g')
MESSAGE=$(echo "$MESSAGE" |sed 's@%rw_status@NORMAL@g')
MESSAGE=$(echo "$MESSAGE" |sed 's@%lc_status@NORMAL@g')

echo "$MESSAGE" >$REPORT_FILE
sendemail -f $MAIL_FROM -t $MAIL_TO -u $MAIL_SUBJECT -o message-      file=$REPORT_FILE -s $MAIL_SERVER -xu $MAIL_USER -xp $MAIL_PASS

else
################
#ERRORS OCCURED#
################

MAIL_SUBJECT=$(echo "$MAIL_SUBJECT" |sed 's@%status@[ERROR]@g')

if [ $cy_status -eq 0 ]; then
  MESSAGE=$(echo "$MESSAGE" |sed 's@%cy_status@NORMAL@g')
else
  MESSAGE=$(echo "$MESSAGE" |sed 's@%cy_status@ERROR@g')
fi

if [ $ug_status -eq 0 ]; then
  MESSAGE=$(echo "$MESSAGE" |sed 's@%ug_status@NORMAL@g')
else
  MESSAGE=$(echo "$MESSAGE" |sed 's@%ug_status@ERROR@g')
fi

if [ $rw_status -eq 0 ]; then
  MESSAGE=$(echo "$MESSAGE" |sed 's@%rw_status@NORMAL@g')
else
  MESSAGE=$(echo "$MESSAGE" |sed 's@%rw_status@ERROR@g')
fi

if [ $lc_status -eq 0 ]; then
  MESSAGE=$(echo "$MESSAGE" |sed 's@%lc_status@NORMAL@g')
else
  MESSAGE=$(echo "$MESSAGE" |sed 's@%lc_status@ERROR@g')
fi

  echo "$MESSAGE" >$REPORT_FILE

  cat /dev/null >$ERROR_LOG
  find /tmp/ -name \*.$$ -exec cat {} \; >>$ERROR_LOG
  cp $ERROR_LOG .
  sendemail -f $MAIL_FROM -t $MAIL_TO -u $MAIL_SUBJECT -o message-file=$REPORT_FILE -a error_log-$$.txt -s $MAIL_SERVER -xu $MAIL_USER -xp  $MAIL_PASS
  rm error_log-$$.txt

fi

#Cleanup
rm /tmp/*.$$ 2>/dev/null
rm /tmp/*$$.txt 2>/dev/null

Observe como estou monitorando o status de saída do rsync para determinar qual deve ser a mensagem e o assunto do meu e-mail. No meu caso, estou descartando a saída normal (1 > / dev / null) e mantendo apenas a saída de erro padrão (2 > $ error_log). Você pode usar apenas o > > operador se você quiser manter toda a saída. Você também pode ajustar para incluir o registro na mensagem em vez de um anexo por conveniência, se estiver lendo seu correio do terminal.

Talvez pareça um exagero para uma pergunta relativamente simples, mas acho que isso descreve bem o que você está tentando fazer. Você precisa construir sua mensagem enquanto executa seu comando através de um script intermediário e enviá-lo mais tarde. Se você achar o código acima útil e tiver alguma dúvida, não hesite em perguntar nos comentários.

    
por 22.02.2017 / 00:51