I liked @Artur Meinild's answer, and I wanted to dig a bit deeper, because I really wanted to understand how this works. I had a look at the source code of cron as shipped by Ubuntu, by enabling the source code repositories and running apt-get source cron
. Here's what I learned:
cron just uses the command sendmail
To send an email, cron simply runs the command sendmail
, like this:
/usr/sbin/sendmail -FCronDaemon -i -B8BITMIME -oem "$MAILTO"
(the exact command-line arguments might differ, but that's the gist of it)
MAILTO
is an environment variable that can be set in the crontab. If it is not set, then LOGNAME
environment variable is used instead. Cron sets LOGNAME
to be the username of the Linux user. From man 5 crontab
:
Several environment variables are set up automatically by the cron(8) daemon. SHELL
is set to /bin/sh
, and LOGNAME
and HOME
are set from the /etc/passwd
line of the crontab's owner. PATH
is inherited from the environment. HOME
, SHELL
, and PATH
may be overridden by settings in the crontab; LOGNAME
is the user that the job is running from, and may not be changed.
In addition to LOGNAME
, HOME
, and SHELL
, cron(8) will look at MAILTO
and MAILFROM
if it has any reason to send mail as a result of running commands in this crontab.
If MAILTO
is defined (and non-empty), mail is sent to the user so named. MAILTO
may also be used to direct mail to multiple recipients by separating recipient users with a comma. If MAILTO
is defined but empty (MAILTO=""
), no mail will be sent. Otherwise mail is sent to the owner of the crontab.
If MAILFROM
is defined, the sender email address is set to MAILFROM
. Otherwise mail is sent as "root (Cron Daemon)".
By default, Ubuntu does not ship with the command sendmail
installed. In that case, you will notice in the logs this error:
Feb 10 17:27:01 desktop-ubuntu CRON[36079]: (CRON) info (No MTA installed, discarding output)
Several different packages provide a sendmail
command on Ubuntu. One that is often recommended is postfix:
$ sudo apt install postfix
(When prompted in the installation, I chose the "Local only" option, since I wasn't interested in sending email over the Internet.)
Postfix installs a command sendmail
in order to be compatible with other packages like cron that expect to a sendmail
command to be found. Other packages that also install sendmail
are:
$ apt-file search -F /usr/sbin/sendmail
courier-mta: /usr/sbin/sendmail
dma: /usr/sbin/sendmail
esmtp-run: /usr/sbin/sendmail
exim4-daemon-heavy: /usr/sbin/sendmail
exim4-daemon-light: /usr/sbin/sendmail
lsb-invalid-mta: /usr/sbin/sendmail
masqmail: /usr/sbin/sendmail
msmtp-mta: /usr/sbin/sendmail
nullmailer: /usr/sbin/sendmail
opensmtpd: /usr/sbin/sendmail
postfix: /usr/sbin/sendmail
ssmtp: /usr/sbin/sendmail
It seems that if postfix is installed with the "local only" configuration, then mail sent to a Linux gets stored in this location /var/mail/<username>
. Here is some example content of this file once a cron job running echo hi
has run:
$ less /var/mail/$USER
From flimm@desktop-ubuntu Tue Feb 14 08:54:01 2023
Return-Path: <flimm@desktop-ubuntu>
X-Original-To: flimm
Delivered-To: flimm@desktop-ubuntu
Received: by desktop-ubuntu (Postfix, from userid 1000)
id 9C7137E12E4; Tue, 14 Feb 2023 08:54:01 +0100 (CET)
From: root@desktop-ubuntu (Cron Daemon)
To: flimm@desktop-ubuntu
Subject: Cron <flimm@desktop-ubuntu> echo hi
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/flimm>
X-Cron-Env: <LOGNAME=flimm>
Message-Id: <20230214075401.9C7137E12E4@desktop-ubuntu>
Date: Tue, 14 Feb 2023 08:54:01 +0100 (CET)
hi
If you prefer, you can use a mail client like mutt (on the command-line) or Thunderbird (with a GUI) to view these emails stored in this location.
References: