(CRON)信息(未安装MTA,丢弃输出)在系统日志中的错误。

我在一些服务器上安装了Ubuntu 12.04.1 LTS的最新版本。
我没有添加任何cron作业或编辑过这些服务器上的crontab,然而,在每台机器大约相同的时间,我会遇到75%的CPU占用率飙升,并且在飙升时刻的syslog中会出现以下信息:
CRON[8380]: (CRON) info (No MTA installed, discarding output)

我已经安装了mono-complete并且正在运行一个service stack webserver。
有什么最好的方法可以阻止这种情况发生吗?我希望能够消除CPU的峰值。

每天都在6:25?那些是来自/etc/cron.daily/的脚本。我只有一个尝试发送邮件的脚本:popularity-contest。检查一下你的脚本,看看哪个脚本正在尝试发送邮件?这应该可以缩小范围。然后使用'chmod 0644 /etc/cron.daily/script-name'来阻止执行。 - user8290
14个回答

Linux使用邮件给用户发送通知。大多数Linux发行版都有一个包含MTA(邮件传输代理)的邮件服务安装。然而,Ubuntu没有。
为了解决这个问题,你可以安装一个邮件服务,例如postfix。
sudo apt-get install postfix

或者你可以忽略它。我认为cron无法发送消息与CPU上涨无关(这与cron正在运行的基础作业相关联)。安装一个MTA可能是最安全的选择,然后阅读这些消息(mutt是一个很好的系统邮件阅读器)。

9安装Postfix是个好主意吗?哪个MTA最容易使用? - endolith
5Postfix是Linux上最广泛使用的邮件服务器,坚持使用它。 - Rápli András
11值得指出的是,在与cron一起使用时(也就是说,如果您不想实际发送电子邮件),在安装过程中,您应该回答仅配置本地使用。 - steffen
1我所知道的唯一检查邮件的方法是使用mailutils(Debian)提供的mail命令,如果有更好的内置于Postfix的方法吗? - ThorSummoner
一个更简单易用的MTA是msmtp-mta(通常与msmtp本身一起使用)。 - pyrsmk
2后缀是那种实际上不通过互联网发送电子邮件而是创建一个本地邮箱,可以从命令行中检查的吗?最好提一下。(是的,是这样的,我使用这个答案在我的其他服务器上验证了:https://serverfault.com/a/100743) - endolith
邮件发送了53个字节的输出,但从MTA收到了0x004b的状态。 - undefined

这是因为您的cron作业产生了输出,然后cron守护进程尝试将该输出发送给您(即root)。如果您不需要这些输出,最简单的解决方法是在crontab中将其丢弃。
sudo crontab -e

并且在每个作业中添加>/dev/null 2>&1
* * * * * yourCommand >/dev/null 2>&1

17这种方法的问题在于它没有解释高CPU使用率的原因。Cron显然试图进行沟通,而这种方法实际上只是忽略了输出。我更倾向于处理输出而不是丢弃它,以防有有用的调试信息。 - Oli
1Oli,虽然这是一个老问题,但我遇到了完全相同的问题,只不过是在树莓派上。我在日志中看到了一堆“未安装MTA,丢弃输出”的消息,我的程序最终会自动停止运行。我认为这是因为CPU峰值导致的。看起来所有对这个问题的回答似乎都忽略了这一点。 - ThN
22为了保留输出结果,请将命令放入脚本中,并将stdout和stderr导向logger。例如,yourCommand >/dev/null 2>&1 | logger -t mycmd。这样可以将输出结果保存在syslog中,同时避免MTA的投诉。 - CivMeierFan
5@rob:隐藏输出并不能解决问题。 - pyrsmk
3对于阅读 @CivMeierFan 的评论的人们 - 不要在那里加上 > /dev/null :) 请参考 Michael Hunter 的答案获取更多细节。 - Nacht
对于礼仪,我在给出负评的同时也想加上一条评论:这个所谓的“解决方案”真是糟糕透了。或许它修复了错误信息和CPU占用过高的问题,但是像这样把问题掩盖起来的心态正是我们无法拥有美好事物的原因。 - Steven Lu

这是一个老问题,但在某些情况下有一个额外的答案是很有用的。
将您的cron命令的输出通过“logger”传输,以便它们最终出现在syslog中。
这比安装postfix要稍微容易一些,并且它将此输出放入与其他日志并列的syslog中。此命令将捕获stdout和stderr,因此您将不会看到“No MTA installed”消息,并且您将在syslog中看到所有输出。
示例cron条目:
0 3 * * * (cmd1;  cmd2) 2>&1 | logger -t mycmd

您可以使用以下命令查看带有标签mycmd的日志:
grep 'mycmd' /var/log/syslog

管道在cron作业中起作用吗? - CivMeierFan
3这对我来说非常完美。日志可以通过journalctl访问。 - pprishchepa
3完美答案。 - Ayushi Agarwal
6这个答案应该被标记为解决方案,因为它以现代的方式通过Syslog服务完全解决了问题。 - Roman Shishkin
1这应该是答案!简单而且非常有效! - whileone
1轻巧优雅的解决方案,使用内置工具。运行完美无缺。 - Petr Javorik
cron在计划任务执行失败且退出码非零时发送电子邮件,即使没有输出。这种方式无法捕获非零的退出码,并且会抑制cron发送的电子邮件,因为命令的第一部分的退出码被丢弃了。 - Flimm

在我的情况下,这条信息暗示了bash脚本的权限问题,但是直到我安装了MTA才能看到。
如建议所示,我运行了:
sudo aptitude install postfix

我在设置过程中选择了“本地”,然后再次运行cron作业。
sudo tail -f /var/mail/<user>

在我的情况下,我替换了

<user>

使用"root"权限。 然后,我能够看到与权限相关的错误输出。

9非常感谢您对如何检查邮箱以查看工作中的错误的额外评论! - Stuart Allen
<user> 可以替换为 $USER - M Imam Pratama
也许在crontab文件中设置MAILTO=""就足以停止邮件发送并将标准输出和错误输出重定向到命令:* * * * * my_command &>> /var/log/cron.log - bcag2

如前面的回答所述,这是因为您的cron作业产生了输出,然后cron守护进程试图将该输出发送给您。如果您不想(或无法)安装邮件传输代理(MTA),但又想查看输出结果,您可以将cron作业的输出重定向到日志文件中。请编辑您的crontab文件。
crontab -e

(如果问题是与root的crontab有关,请使用sudo) 并在每个命令后添加>> /some/log/file 2>&1,如下所示:
0 3 * * * cmd  >> /some/log/file 2>&1
>> /some/log/file将标准输出发送到指定文件, 附加到任何现有内容中, 而2>&1将错误消息发送到同一位置。)
如果一行上有多个命令, 用;&&&||分隔, 则应为每个命令执行上述操作,如下所示:
0 3 * * * cmd1 >> /some/log/file 2>&1; cmd2 >> /some/log/file 2>&1
或者将它们分组,像这样:
0 3 * * * (cmd1; cmd2) >> /some/log/file 2>&1
如果命令行以&结尾, 在命令之后但&之前插入重定向。  如果有用|(管道)分隔的命令, 简单的解决方案是将它们分组:
0 3 * * * (cmd1 | cmd2) >> /some/log/file 2>&1
但请参阅下面的最后一段。
如果你想忽略标准输出,只捕获标准错误输出, 可以使用> /dev/null 2>> /some/log/file。 将日志文件放在任何你想要的地方 - 你的主目录、 /var/log,甚至是/tmp,如果你确定不需要保留它。
然后在作业运行后查看日志文件。
如果你发现一堆混乱的交错信息, 可能是程序同时写入标准输出和标准错误输出, 但协调性很差。在这种情况下,尝试将它们写入单独的文件, 使用>> /some/log/file1  2>> /some/log/file2。你可能需要对管道做类似的处理:
0 3 * * * cmd1 2>> /some/log/filecmd1err | cmd2 >> /some/log/filecmd2 2>&1
(最好为由“&”分隔的命令使用单独的文件。)

这是许多情况下的最佳解决方案。如果不需要,就无需给任何人发送电子邮件,而且在整个过程中也不会丢失任何数据。“2&>1”将错误信息导入到相同的输出文件中。 - Akaisteph7

在crontab中添加以下内容作为第一行:
MAILTO=""

这样做将阻止 cron 尝试发送电子邮件。

9不要在 MAILTO="" 后面加上任何注释 (#),否则它将无法正常工作。 - SBF
有没有一种全局设置的方法?比如在/etc/default/cron中可以设置吗? - Freedo

如果你不想安装一个邮件传输代理(目前我没有这个需求),你可以将cron作业的结果导入到日志文件中。
sudo crontab -e

然后,你的定时任务将会是这样的。
0 3 * * * /cmd/to/run >> /var/log/somelogfile.log

然后你可以直接跟踪日志,看看发生了什么。
sudo tail -f -n 50 /var/log/somelogfile.log

这是我在任何我看到系统日志中的消息的服务器上一直在做的事情


1我已经做过这个,但是文件中没有添加任何日志记录。 - pir
你确定cron任务一直在运行吗? - Andrew MacNaughton
是的,系统日志显示它正在启动。 - pir
6你需要在行尾加上'2>&1',以将标准错误输出捕获到文件中。 - MattSmith
@MattSmith 这个没有任何作用,文件不存在。 - endolith

添加/dev/null 2>&1到cron作业命令的一个副作用是,它会丢弃STDERRSTDOUT(标准错误以及输出)。如果您不想从cron收到任何电子邮件,那么这很好。但是,如果您希望将错误发送到电子邮件,请改用>/dev/null阅读此博客文章以获取更多解释
但是,您仍然需要安装MTA(邮件传输代理)来发送错误电子邮件。使用以下命令安装Postfix非常简单:sudo apt-get install postfix

据我所了解,'>/dev/null'只会将它们发送到黑洞,而'>/dev/null 2>&1'则会丢弃所有错误。如果我想要将错误记录在日志中但不发送邮件,我应该使用什么?现在我不再收到邮件(正如我所希望的),但是出现了难看的“no MTA…”提示。 - Pit
2据我所知,除了将输出发送到电子邮件之外,没有其他记录输出的方法。你能做的最接近的事情是设置本地邮件传递的postfix(如果你运行“sudo apt-get install postfix”,它会提示你是否要设置本地传递)。虽然一开始看起来有点麻烦,但实际上效果要好得多。每当我通过ssh登录时,如果以前的作业失败了,我就会在机器上看到一封新的电子邮件。我觉得这比检查日志更方便。 - paneer_tikka


这个 - 结合迈克尔·亨特的回答:https://askubuntu.com/a/967798/72260。 - LAFK says Reinstate Monica

首先,安装postfix,可以解决这个问题
sudo apt-get install postfix
如果是Ubuntu,你可以编辑crontab文件
sudo vim /etc/crontab
注意,编辑顶部文件,而不是第一行的任何代码,并输入
MAILTO=root // 当前系统用户
当执行任何任务时,你会收到一封电子邮件
mail

1你的回答看起来不错,但是我没能理解所有的指示。也许你可以改进一下。 - zx485