如果我运行crontab -e
,Ubuntu 会显示当前用户的默认 cron 作业:
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
请注意以下部分:
crontab 作业的输出(包括错误)通过电子邮件发送给 crontab 文件所属的用户(除非重定向)。
我如何查看此输出?哪些电子邮件与我的 Linux 用户关联?
如果我看一下grep CRON /var/log/syslog
,我会看到如下几行:
Feb 10 17:27:01 desktop-ubuntu CRON[36079]: (CRON) info (No MTA installed, discarding output)
我猜 MTA 指的是邮件传输代理。输出似乎被丢弃了。
就我个人而言,我希望将输出保存在某个地方,而不是转到互联网上的真实电子邮件地址。但我的问题更多的是关于理解默认行为。
答案1
为了让 cron 发送电子邮件,您需要安装 postfix 或其他 MTA(邮件传输代理)。
如果没有设置特定的电子邮件地址,邮件将被递送至内部用户电子邮件地址/var/mail/<username>
。
您还可以使用变量指定 cron 发送到的外部电子邮件地址MAILTO
。因此,在您的 crontab 中,设置:
[email protected]
然后 cron 将向该地址发送电子邮件。
如果要禁用 cron 发送电子邮件,请在 crontab 中设置:
MAILTO=""
这就是您控制默认行为的方式。
答案2
我喜欢@Artur Meinild 的回答,我想深入挖掘一下,因为我真的想了解它是如何工作的。我通过启用源代码存储库并运行查看了 Ubuntu 附带的 cron 源代码apt-get source cron
。以下是我了解到的内容:
cron 只使用命令sendmail
要发送电子邮件,cron只需运行命令sendmail
,如下所示:
/usr/sbin/sendmail -FCronDaemon -i -B8BITMIME -oem "$MAILTO"
(确切的命令行参数可能有所不同,但这就是它的要点)
MAILTO
是可以在 crontab 中设置的环境变量。如果未设置,则LOGNAME
使用环境变量。Cron 设置LOGNAME
为 Linux 用户的用户名。来自man 5 crontab
:
cron(8) 守护进程自动设置了几个环境变量。
SHELL
设置为/bin/sh
,和LOGNAME
和从crontab 所有者的行HOME
设置。从环境中继承。 ,,和可能会被 crontab 中的设置覆盖;是运行作业的用户,并且不能更改。/etc/passwd
PATH
HOME
SHELL
PATH
LOGNAME
除
LOGNAME
、HOME
和之外SHELL
,cron(8) 还会查看MAILTO
是否MAILFROM
有任何理由通过运行该 crontab 中的命令来发送邮件。如果
MAILTO
已定义(且非空),则将邮件发送给指定用户。MAILTO
还可用于将邮件发送给多个收件人,方法是用逗号分隔收件人用户。如果MAILTO
已定义但为空(MAILTO=""
),则不会发送邮件。否则将邮件发送给 crontab 的所有者。如果
MAILFROM
已定义,则发件人电子邮件地址设置为MAILFROM
。否则邮件将以“root(Cron Daemon)”的身份发送。
默认情况下,Ubuntu 不附带sendmail
安装的命令。在这种情况下,您会在日志中注意到此错误:
Feb 10 17:27:01 desktop-ubuntu CRON[36079]: (CRON) info (No MTA installed, discarding output)
Ubuntu 上有几种不同的软件包提供sendmail
命令。最常推荐的是 postfix:
$ sudo apt install postfix
(当安装提示时,我选择了“仅限本地”选项,因为我对通过互联网发送电子邮件不感兴趣。)
Postfix 安装命令sendmail
是为了与其他需要sendmail
找到命令的软件包(如 cron)兼容。同时安装的其他软件包sendmail
包括:
$ 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
似乎如果 postfix 安装时选择了“仅限本地”配置,那么发送到 Linux 的邮件就会存储在这个位置/var/mail/<username>
。以下是 cron 作业运行后该文件的一些示例内容echo hi
:
$ 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
如果你愿意,你可以使用像 mutt(在命令行上)或 Thunderbird(使用 GUI)来查看存储在此位置的电子邮件。
参考:
- 邮件到底从哪里来?作者 Christoph Mewes
- crontab(5) 手册页(针对文件格式)
- crontab(1) 手册页(用于命令)