Cron:只有当输出包含string时才发送邮件

如果输出( stderr )包含某个string,我可以让原因cron只发送电子邮件吗?

我知道这个答案,但我运行的命令不区分stdout / stderr ,它总是只输出到stdout ,所以我需要寻找一个string。

到目前为止,我得到了这个,它基本上工作除了grep不传递给邮件命令的输出,所以我只是得到一个空的电子邮件:

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

我如何从电子邮件中的mycommand获取整个输出?

我强烈build议你把逻辑放到一个脚本中,然后在cron中运行这个脚本,而不是尝试在cron中创build一个脚本。 这样你就可以很容易地在cron之外testing它,例如:

 #!/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退出状态的检查,传递正在运行的命令,匹配的string和电子邮件地址作为参数等。

这可能工作。

  #!/ bin / sh的
 COMMAND =`mycommand`
 FINDSTR =“更新完成”

 ANSWER =`$ COMMAND |  grep $ FINDSTR` 

如果$ ANSWER; 然后
   echo $ ANSWER> mail -s'续订完成'[email protected]
科幻

以下是我如何做到这一点:

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

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

备份状态报告来自:%主机名

networkingconfiguration:
%net_config

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

所有以%开头的单词被视为variables,并在稍后的脚本中被sed代替。
%主机名和%net_config用于标识电子邮件来自哪台计算机。
以_STATUS结尾的variables被replace为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)。 如果你想保留所有的输出,你可以使用>>操作符。 如果您正在从terminal读取邮件,则还可以调整为在邮件中包含日志而不是附件。

也许它看起来像一个相对简单的问题矫枉过正,但我​​认为它概述了你正在尝试做什么。 您需要通过中间脚本运行命令来构build消息,然后再发送。 如果您发现上面的代码有用,并且有任何问题,请随时在评论中提问。