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 &
.)