我可以让 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)。如果您想保留所有输出,则可以使用 >> 运算符。如果您从终端阅读邮件,您还可以调整以将日志包含在消息中而不是附件中,以方便使用。
对于一个相对简单的问题来说,这看起来可能有点过头了,但我认为它很好地概括了你想要做的事情。你需要在通过中间脚本运行命令时构建消息,然后稍后发送。如果你觉得上面的代码有用,并且有任何疑问,请随时在评论中提问。