Cron:仅当输出包含字符串时才发送邮件

Cron:仅当输出包含字符串时才发送邮件

我可以让 cron 仅在输出(stderr)包含特定字符串时发送电子邮件吗?

我知道这个答案但是我运行的命令没有区分stdout/ stderr,它总是只输出到stdout,所以我需要查找一个字符串。

到目前为止我已经得到了这个,它基本上有效,除了 grep 没有将输出传递给 mail 命令,所以我只收到一封空的电子邮件:

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

我如何获得全部的电子邮件中是否包含来自 mycommand 的输出?

答案1

我强烈建议您将逻辑放入脚本中并在 cron 中运行该脚本,而不是尝试在 cron 中编写一行脚本。这样,您就可以在 cron 之外轻松测试它,例如:

    #!/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

您可以添加对 mycommand 退出状态的检查,传递正在运行的命令、正在匹配的字符串和电子邮件地址作为参数等。

答案2

这可能有用。

/bin/sh #!/bin/sh 复制代码
COMMAND=`我的命令`
FINDSTR="续订已完成"

答案 = `$COMMAND | grep $FINDSTR`

如果 $ANSWER; 那么
  echo $ANSWER > mail -s'续订完成'[电子邮件保护]

答案3

以下是我的做法:

在这种情况下,我需要备份 4 个数据库(转储),如果一切正常,我希望收到一封提及此事的电子邮件。如果我遇到错误,我希望收到一封主题不同的邮件来指出错误,邮件正文中包含失败的数据库,并将错误日志附加到电子邮件中。

第一个文件(/root/templates/ylatis-backup.txt)只是一个消息正文模板:

备份状态报告来自:%hostname

网络配置:
%net_config

数据库备份:
ylatis-cy :%cy_status
ylatis-ug :%ug_status
ylatis-rw :%rw_status
ylatis-lc :%lc_status

所有以 % 为前缀的单词都被视为变量,并在脚本中稍后由 sed 替换。
%hostname 和 %net_config 用于识别电子邮件来自哪台计算机。
以 _status 结尾的变量被替换为单词 NORMAL 或 ERROR,这样我就可以知道哪里出了问题。

#!/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

请注意我如何监控 rsync 的退出状态来确定我的电子邮件的消息和主题应该是什么。就我而言,我丢弃了正常输出(1>/dev/null)并仅保留标准错误输出(2>$error_log)。如果您想保留所有输出,则可以使用 >> 运算符。如果您从终端阅读邮件,您还可以调整以将日志包含在消息中而不是附件中,以方便使用。

对于一个相对简单的问题来说,这看起来可能有点过头了,但我认为它很好地概括了你想要做的事情。你需要在通过中间脚本运行命令时构建消息,然后稍后发送。如果你觉得上面的代码有用,并且有任何疑问,请随时在评论中提问。

相关内容