Answers:
由于您不关心输出,因此可以将作业的STDOUT重定向到,/dev/null
并通过邮件(使用MAILTO
环境变量)发送STDERR 。
因此,例如:
...
...
MAILTO=foobar@example.com
...
...
* * * * * /my/script.sh >/dev/null
将仅在STDERR(带有STDERR)上有输出时发送邮件,并丢弃STDOUT。
当然,这是假定在STDERR上编写程序时失败了。并非总是如此。如果您对该程序拥有控制权,则可以这样做。对于任何复杂的情况,您都应该编写某种运行命令的包装程序,并相应地发送邮件。并将包装器作为cron
工作。
在chronic
从命令moreutils悄悄运行一个命令,除非它失败。
引用其手册:
慢性运行命令,并安排其标准输出和标准错误仅在命令失败(退出非零或崩溃)时显示。如果命令成功执行,则任何多余的输出都将被隐藏。
慢性病的常见用法是执行cron工作。不必试图使命令保持安静,并且不必处理成功时包含意外输出的邮件,而不必在失败时不进行详细的输出,而是可以始终冗长地运行该命令,并使用chronic隐藏成功的输出。
如果出现错误,我如何只接收来自cron的电子邮件?
您可以使用cronic封装您的cron调用,cronic是一个吃cron输出的shell脚本,除非被调用的进程的返回码为非零或没有非跟踪错误输出。
要使用cronic,请将脚本下载到合适的位置,例如/usr/local/bin
。您的crontab条目必须以脚本的路径(例如/usr/local/bin/cronic
)为前缀,或者简单地以cronic
您PATH
的设置正确为前提。
请注意,“错误”在您的问题中定义不明确,需要仔细定义。为了使cronic有用,您必须以定义错误条件的方式之一,确保用cronic报告错误包装的作业。隐式的报告方法(例如将文本字符串写入)STDOUT
将需要进一步考虑,以使其与cronic或其他cron报告机制兼容。
有其他包装器,可从cronic网站链接:
cronic
涉及到chronic
,或者是只是巧合吗?
这是我多年成功使用的另一种形式-捕获输出并仅在错误时打印出来。这不需要临时文件,并保留所有输出。重要的部分是2>&1
将STDERR重定向到STDOUT的部分。
1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT"
1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT" | mail -s "Failed to backup" an@email.address
1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || {echo "$OUTPUT" ; ls -ltr /backup/dir ; }
这将适用于简单的命令。如果您要处理复杂的管道(find / -type f | grep -v bla | tar something-or-other
),则最好将命令移至脚本中并使用上述方法运行脚本。原因是,如果管道的任何部分输出到STDERR,您仍然会收到电子邮件。
$OUTPUT
使用引号:"$OUTPUT"
。
我可能一直都没有想过,但是
* * * * * yourthing.sh >/tmp/yourthing.log && rm -f /tmp/yourthing.log; cat /tmp/yourthing.log 2>/dev/null
在通常情况下,会将所有内容重定向到一个临时文件(您可能希望使用它mktemp
来获得唯一的文件名),如果文件成功,则将cat
其删除,如果内容仍然存在,则将其再次删除(即,退出yourthing.sh)且有错误情况),由cron邮递员领取。
如果有内存可用,那么cron在没有输出的情况下就不会发送任何信息,因此,如果日志文件为空或不存在,则不会发生任何事情。(我们将错误消息重定向出去。)