Cron 使用 STDERR 但不是 STDOUT 发送电子邮件?
Posted
技术标签:
【中文标题】Cron 使用 STDERR 但不是 STDOUT 发送电子邮件?【英文标题】:Cron send email with STDERR but NOT STDOUT? 【发布时间】:2010-11-26 15:49:48 【问题描述】:我有一些每天在 cron 中运行的 python 脚本。我怎样才能让 cron 向我发送电子邮件仅当我的脚本有 STDERR 输出时?我希望能够向多个收件人发送邮件,并为每个 cron 条目单独设置主题行。
我试过了:
./prog > /dev/null | mail . . .
但它不起作用——当没有 STDERR 时,我仍然收到空白电子邮件。我需要在脚本本身中执行此操作吗?
对不起,如果这看起来很基本,我已经用谷歌搜索了很多,但似乎找不到简洁的答案。
【问题讨论】:
【参考方案1】:对于 cron,您不需要通过邮件进行管道传输。 cron 守护进程会自动将您的命令的任何输出邮寄给您。您的 crontab 条目应如下所示:
# every minute
* * * * * ./prog >/dev/null
如果没有 STDERR 输出,您将不会收到任何邮件。
【讨论】:
"如果没有 STDERR 输出,您将不会收到任何邮件。"这是真的,如果我设置 MAILTO="me@mine"。但是,如果通过管道传送到 mail(1),则不是这样。 “除了 LOGNAME、HOME 和 SHELL 之外,如果由于在 `this' crontab 中运行命令而有任何理由发送邮件,cron 将查看 MAILTO。” -- ss64.com/osx/crontab.html 但是,我需要设置邮件的 主题,而 cron 本身无法做到这一点(恕我直言)。所以我被困在使用邮件中,这让我们回到了我原来的问题。 这种方法的问题是它假设stdout
在发生错误时不会包含任何有用的信息。 cronic
解决方案更适合我。【参考方案2】:
-s
文件测试将告诉您文件是否存在并且大小大于零。
./prog >/dev/null 2>some/file ; if [ -s some/file ] ; then mail < some/file ; fi
【讨论】:
我最终使用了这种方法的变体。谢谢 mobrule 找到了一篇对我有帮助的好文章。xaprb.com/blog/2006/06/06/what-does-devnull-21-mean【参考方案3】:mail v1.6 可以选择不发送正文为空的邮件:
-E Do not send messages with an empty body.
This is useful for piping errors from cron(8) scripts.
这可能就是你要找的。p>
【讨论】:
【参考方案4】:你问的问题不正确。当您使用 mail(1) 发送电子邮件时,它在 cron 中不再相关。您真正需要的是通过管道将 stderr 传输到邮件的标准输入。普通管道是从标准输出到标准输入,所以解决这个问题的最简单方法是重定向:
/prog > /dev/null ; 2>&1 | mail ...
或者由于重定向顺序混乱而不太清楚:
/prog 2>&1 > /dev/null | mail ...
【讨论】:
很好的答案和将 stderr 和 stdout 都定向到邮件命令的正确技术。第二个示例将 stdout 丢弃在地板上,仅将 stderr 发送到 mail 命令。 我认为这是本意。【参考方案5】:有一个很好的工具叫做cronic 可以做到这一点。它是moreutils 包的一部分。
【讨论】:
在我的 Ubuntu 12.04 上,chronic
(不是 cronic
)捆绑在 moreutils
中,它是用 perl 而不是 bash 编写的,但似乎具有相同的目的。还是谢谢!
chronic
如果程序以错误退出,则似乎同时输出 STDOUT 和 STDERR,或者如果程序干净退出,则两者都不输出。那对我不起作用。我想要一个 chronic
过滤掉 STDOUT,独立于退出代码。一个简单的重定向最适合我。
请注意cronic
和chronic
的行为是不同的:chronic
(moreutils
, Perl) 如果退出代码为 0,则不会输出任何内容,即使 STDERR 上有内容. cronic
(habilis.net, bash) 如果 STDERR 上有内容,则输出所有内容,即使退出代码为 0。【参考方案6】:
如果您的 SCRIPT 有可能产生您希望收到通知的 STDERR 的命令,那么您需要在脚本本身中使用 mail 或 mailx 调用(if then else 或 )。 cron 作业 STDOUT 和 STDERR 重定向仅适用于 cron 作业 EXECUTION STDOUT 和 STDERR。 hkmaly 在 n 上做得对
【讨论】:
以上是关于Cron 使用 STDERR 但不是 STDOUT 发送电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Windows 中访问继承的匿名管道句柄,而不是 stdout、stderr 和 stdin?
输出重定向是不是按顺序写入 stdout 和 stderr 信息?
使用 Autohotkey 读取 StdErr 和 StdOut