339

I have a fresh install of Ubuntu 12.04.1 LTS an a number of servers.

I have not added any cron jobs or edited my crontab on those servers, however, at around the same time for each machine, I get a 75% CPU spike and the following info in my syslog at the time of the spike:

CRON[8380]: (CRON) info (No MTA installed, discarding output)

I have mono-complete installed and am running a service stack webserver.

What is the best way for me to stop this from happening? I would like to be able to remove the CPU spike.

3
  • Every day at 6:25? Those are scripts from /etc/cron.daily/. I have only one trying to send mail: popularity-contest. Look though your scripts and see which script is trying to send mail? That should narrow it down. Then 'chmod 0644 /etc/cron.daily/script-name' to prevent execution.
    – user8290
    Nov 27, 2012 at 16:11
  • For me this message relates to permission issues. So cron not run in specific time. The cron user doesn't have sufficient permissions to write logs on specific location. Change the ownership of directory solve the problem and now job can run at scheduled time.
    – EsmaeelE
    Mar 19 at 0:54
  • Running ps aux | grep {process_name} help to find out script not run by crontab.
    – EsmaeelE
    Mar 19 at 1:03

14 Answers 14

263

Linux uses mail for sending notifications to the user. Most Linux distributions have a mail service including an MTA (Mail Transfer Agent) installed. Ubuntu doesn't though.

You can install a mail service, postfix for example, to solve this problem.

sudo apt-get install postfix

Or you can ignore it. I don't think the inability of cron to send messages has anything to do with the CPU spike (that's linked to the underlying job that cron is running). It might be safest to install an MTA and then read through the messages (mutt is a good system mail reader).

7
  • 9
    Is postfix a good thing to install? Which MTA is easiest to use?
    – endolith
    Nov 26, 2013 at 4:34
  • 5
    postfix is the most widely used mail server for linux, stick to it Dec 3, 2014 at 17:03
  • 11
    It is worth pointing out that for use with cron (that is if you don't want to actually send email outwards) during the installation procedure you should answer to configure for local use only.
    – steffen
    Oct 27, 2017 at 10:16
  • 2
    the only way I know to check mail is mail provided by mailutils (debian), if there a better way built in to postfix? Jun 15, 2019 at 17:30
  • 2
    Is postfix the one that doesn't actually send emails over the internet but creates a local mailbox that you can check from the command line? Would be good to mention that. (Yep it is, used this answer to verify on my other server: serverfault.com/a/100743 )
    – endolith
    Sep 24, 2022 at 16:27
131

This happens because your cron jobs are producing output and then the cron daemon tries to email that output to you (i.e. root). If you don't need that output, the easiest way to solve this is to discard it at the crontab:

sudo crontab -e

and add >/dev/null 2>&1 to every job:

* * * * * yourCommand >/dev/null 2>&1
6
  • 17
    The problem with this approach is it doesn't explain the high CPU usage. Cron is clearly trying to be communicative and this is essentially just ignoring the output. I'd be more inclined to handle the output than discard it, just in case there's useful debug info.
    – Oli
    Jan 2, 2014 at 14:39
  • 1
    Oli, even though this is an old question, I am experiencing the same exact issue but it is on Raspberry PI. I see bunch of No MTA installed, discarding output message in the log and my program eventually stops running on its own. I believe it is because of CPU spike. It looks like all the answer posted for this question seem to ignore that.
    – ThN
    Jan 18, 2017 at 15:37
  • 22
    To keep the output, put the command in a script, and pipe stdout and stderr to logger. For example, yourCommand >/dev/null 2>&1 | logger -t mycmd. This will put the output in syslog for safe keeping, and stop the MTA complaints. Feb 13, 2018 at 0:03
  • 5
    @rob : Hiding the output is not a fix.
    – pyrsmk
    Jan 3, 2021 at 15:14
  • 3
    For people reading @CivMeierFan's comment - don't put the > /dev/null in there :) See Michael Hunter's answer for more details.
    – Nacht
    Jan 4, 2021 at 13:42
107

This is an old question but there is an additional answer that is useful in some circumstances.

Pipe the output of your cron command through logger so they end up in the syslog.

It's slightly easier than installing postfix, and it puts this output into syslog alongside your other logs. This command will capture stdout AND stderr so you won't see the No MTA installed message and you'll see all your output in the syslog.

Example cron entry:

0 3 * * * (cmd1;  cmd2) 2>&1 | logger -t mycmd

You can view logs with your tag mycmd using:

grep 'mycmd' /var/log/syslog
9
  • 3
    This works perfectly for me. Logs are available via journalctl. Dec 27, 2019 at 4:33
  • 3
    Perfect Answer. Mar 11, 2021 at 14:08
  • 6
    This answer should be marked as a solution because it exactly solves the question in a modern way with the Syslog service. Nov 25, 2021 at 16:28
  • 1
    This should be the answer! Simple and extremely effective!
    – whileone
    Feb 1, 2022 at 7:01
  • 1
    Lightweight elegant solution using built-in tools. Works perfectly. Feb 17, 2022 at 10:24
92

In my case, the message was hinting at a permissions problem with the bash script, but I couldn't see it until I installed an MTA.

As suggested I ran:

sudo aptitude install postfix

I chose "Local" during setup and after running the cron job again:

sudo tail -f /var/mail/<user>

In my case I replaced

<user>

with "root".

I was then able to see the error output related to permissions.

3
  • 9
    Thank you for the extra comment on how to check the mailbox to see errors from the job! Dec 14, 2016 at 14:08
  • <user> can be replaced with $USER Jun 18, 2022 at 10:13
  • perhaps MAILTO="" in crontab file is enough to stop email and redirect stdout and stderr in command : * * * * * my_command &>> /var/log/cron.log ?
    – bcag2
    Jan 3, 2023 at 15:07
72

As stated in an earlier answer, this happens because your cron jobs are producing output, and then the cron daemon tries to email that output to you.  If you don’t want to (or can’t) install an MTA, but you want to see the output, you can redirect the output of the cron job to a log file.  Edit your crontab file with

crontab -e

(use sudo if the issue is with root’s crontab) and add >> /some/log/file 2>&1 after every command, like this:

0 3 * * * cmd  >> /some/log/file 2>&1

(>> /some/log/file sends the standard output to the named file, appending to any existing content, and 2>&1 sends the error messages to the same place.)

If there are multiple commands on a line, separated by ;, &,  &&  or ||, you should do the above for each command, like this:

0 3 * * * cmd1  >> /some/log/file 2>&1;  cmd2  >> /some/log/file 2>&1

or group them, like this:

0 3 * * * (cmd1;  cmd2)  >> /some/log/file 2>&1

If the command line ends with &, insert the redirection after the command but before the &.  If there are commands separated by | (a pipeline), the simple solution is to group them:

0 3 * * * (cmd1  |  cmd2)  >> /some/log/file 2>&1

but see also the last paragraph, below.

If you want to ignore stdout and capture only stderr, use > /dev/null 2>> /some/log/file instead.  Put the log file wherever you want — your home directory, /var/log, or even /tmp if you’re sure you won’t need to keep it.

Then look at the log file after the job runs.

If you find a mangled mess of interlaced messages, it may be that the program(s) are writing stdout and stderr concurrently with poor coordination.  In that case, try writing them to separate files with >> /some/log/file1  2>> /some/log/file2.  You may need to do something similar with pipelines:

0 3 * * * cmd1  2>> /some/log/filecmd1err  |  cmd2  >> /some/log/filecmd2 2>&1

(It’s probably also best to use separate files for commands separated by &.)

1
  • This is the best solution for many cases. No need to email anyone if not desired and no data is lost in the process. 2&>1 pipes the errors as well into the same output file.
    – Akaisteph7
    Mar 17, 2022 at 15:45
48

In crontab add this as first line:

MAILTO=""

This will prevent cron from trying to send an e-mail.

2
  • 9
    Don't put any comments (#) after MAILTO="" or it won't work
    – SBF
    Mar 29, 2018 at 9:33
  • Is there a way to set this globally? like in /etc/default/cron
    – Freedo
    Jul 5, 2021 at 7:59
30

If you don't want to install an MTA (which I currently have no need for) you can pipe the results of the cron job to a log file.

sudo crontab -e

then with your cron job would look like this.

0 3 * * * /cmd/to/run >> /var/log/somelogfile.log

then you can just tail the log and see what happened

sudo tail -f -n 50 /var/log/somelogfile.log

This is what I have been doing on any server that I see that message in syslog

5
  • 1
    I've done this, but no logging is added to the file.
    – pir
    Aug 6, 2017 at 19:18
  • Are you sure that the cron job as been running? Aug 7, 2017 at 20:15
  • Yes, the system log shows that it's being started.
    – pir
    Aug 7, 2017 at 21:14
  • 6
    You need '2>&1' on the end of the line to capture output to stderr into the file.
    – MattSmith
    Dec 4, 2017 at 0:33
  • @MattSmith That doesn't do anything, the file doesn't exist
    – endolith
    Mar 13, 2021 at 5:34
11

One side effect of adding /dev/null 2>&1 to the cron job command, is that it will discard both STDERR and STDOUT (Standard Error as well as Output). This works fine if you don't want any emails from cron. But if you want your errors to be emailed to you, use >/dev/null instead. Read this blog post for more explanation.

You'll still need to install an MTA (mail transfer agent) to send the error emails though. Postfix is simple enough to install with: sudo apt-get install postfix

2
  • As far as I understood '>/dev/null' will only send them, and '>/dev/null 2>&1' will doscard all errors? What would I have to use to get errors in log but no mails? I now get no mails (as I want it) but the ugly 'no MTA…'
    – Pit
    Feb 5, 2014 at 12:31
  • 2
    afaik, there's no way to log the output other than to send it to emails. The closest thing you can do is to set up postfix for local mail delivery (if you run "sudo apt-get install postfix" it prompts you whether you want to set up local delivery. While this looked like a pain initially, it actually works a lot better. Whenever I log in via ssh, I see a new email on the machine if a previous job has failed. I find it more convenient than having to check the log. Feb 7, 2014 at 4:32
5

You can set MAILTO=”” variable at the start of your crontab file. This will also disable email alert. Edit/Open your cron jobs:

$ crontab -e

At the top of the file, enter:

MAILTO=""

https://www.cyberciti.biz/faq/disable-the-mail-alert-by-crontab-command/

1
2
  1. At first, install postfix, that can resolve the problem

    sudo apt-get install postfix
    
  2. If Ubuntu, you can edit the crontab file

    sudo vim /etc/crontab
    
  3. Attention,edit the top file,not any code in the first line,and enter

    MAILTO=root // current system user
    
  4. When cron executes any task,you will get an email

    mail
    
1
  • 1
    Your answer seems to be good, but I couldn't make sense of all of the instructions. Maybe you can improve it.
    – zx485
    Sep 19, 2018 at 17:00
1

I had this problem using the Kitematic Docker tools.
Go to the magento container and click on exe.

Then run

apt-get update

This is if you're trying to get magento run on kitematic. The log will show this error on the virtual machine:

need update.

Sorry if this got you lost, but that's how it works. You keep getting lost, but just read about it and the pieces will come together one day. Be patient.

1

I had the problem today, but on containers in an isolated network, so no internet... And I was not able to add file redirect on each job since they were automatically deployed...

I found this quick&dirty hack, but it works!

# echo -e '#!/bin/bash\nlogger -t fake-sendmail' > /usr/sbin/sendmail
# chmod a+x /usr/sbin/sendmail

If it can help someone...

1

On Debian, exim4-daemon-light works for me:

apt install exim4-daemon-light

Background information: It was installed on the machine but got replaced when I installed ssmtp manually. After uninstalling ssmtp, the error occured because the system had no package which provided mail-transport-agent.

0

first off all, install postfix

sudo apt-get install postfix

then add logs to you crontab command :

0 0 * * * /home/test.sh /var/log/test.log 2>&1

pay attention to your script requirements, if your script need to run on bash change your command like this.

0 0 * * * /bin/bash -c "/home/test.sh" > /var/log/test.log 2>&1

1
  • sudo dpkg-reconfigure postfix anytime if want reconfigue package
    – yurenchen
    Apr 7, 2023 at 16:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .