如何记录 cron 作业?

Posted

技术标签:

【中文标题】如何记录 cron 作业?【英文标题】:How to log cron jobs? 【发布时间】:2011-06-16 06:04:32 【问题描述】:

我想知道如何准确地看到每次执行时 cron 作业在做什么。日志文件位于何处?或者我可以将输出发送到我的电子邮件吗?我已经设置了在 cron 作业运行时发送日志的电子邮件地址,但我还没有收到任何东西。

【问题讨论】:

看看这篇文章:Managing log files created by cron jobs. 【参考方案1】:
* * * * * myjob.sh >> /var/log/myjob.log 2>&1

会将 cron 作业的所有输出记录到 /var/log/myjob.log

您可以使用mail 发送电子邮件。大多数系统会通过电子邮件将未处理的cron 作业输出发送给root 或相应的用户。

【讨论】:

什么意思说明2>&1:***.com/questions/818255/in-the-bash-shell-what-is-21 如果这个日志文件从未被创建,会出现什么问题? FWIW,如果你想在日志中同时使用 stderrstdout2>&1 必须在间接引用之后:myjob.sh >> /var/log/myjob.log 2>&1 如何在输出文件名中插入YYYY-MM-DD_hh-mm-sec,让每个文件名都不一样,保持不变? @Danijel serverfault.com/a/117365/193377 0 0 * * * /some/path/to/a/file.php > $HOME/date +\%Y\%m\%d\%H\%M\%S-cron.log 2>&1【参考方案2】:

默认情况下,cron 会记录到 /var/log/syslog,因此您可以使用以下命令查看与 cron 相关的条目:

grep CRON /var/log/syslog

https://askubuntu.com/questions/56683/where-is-the-cron-crontab-log

【讨论】:

在 ubuntu 12.04 上,默认没有 .log,即 /var/log/syslog 在 systemd 系统上使用 journalctl | grep cron /var/log/cron 在 AWS Linux AMI 上。 sudo journalctl -u cron cron 的确切记录位置取决于系统。有一个单独的答案,详细说明了如何在 Linux 系统(或更准确地说,使用 syslog 的系统)上配置各种日志记录目标。其他系统可能有不同的方式来配置这些东西。【参考方案3】:

这是我的代码:

* * * * * your_script_fullpath >> your_log_path 2>&1

【讨论】:

">>" 表示将数据附加到文件权? “2>&1”是什么意思,有错误的完整输出,对吧? 基本重定向问题最好在手册中检查。 Stack Overflow 上还有一个关于这些运算符的重复问题的度量标准。但是,是的,大致; >> 追加和 2>&1 表示将标准错误发送到与标准输出相同的位置。【参考方案4】:

至少有三种不同类型的日志记录:

    程序执行前的日志记录,仅记录如果 cronjob 尝试执行该命令。那个位于 /var/log/syslog,正如@Matthew Lock 已经提到的那样。

    程序尝试执行后的错误记录,可以发送到 @Spliffster 提到的电子邮件或文件。我更喜欢记录 到一个文件,因为有了电子邮件 THEN 你有一个新的来源 问题,并检查电子邮件发送和接收是否正常 完美。有时是,有时不是。例如,在一个 你不感兴趣的简单普通台式机 配置 smtp,有时您会更喜欢记录到文件:

     * * * *  COMMAND_ABSOLUTE_PATH > /ABSOLUTE_PATH_TO_LOG 2>&1
    
    我还会考虑检查 /ABSOLUTE_PATH_TO_LOG 的权限,并从该用户的权限运行命令。仅用于验证,同时您测试它是否可能是问题的潜在来源。 程序本身的日志记录,以及用于跟踪目的的错误处理和日志记录。

cronjobs 有一些常见的问题来源: * 要执行的二进制文件的绝对路径。当你从你的 shell,它可能工作,但 cron 进程似乎使用另一个 环境,因此如果你不这样做,它并不总是能找到二进制文件 使用绝对路径。 * 二进制文件使用的库。它或多或少与前一点相同,但请确保,如果只是输入命令的名称,则指的是使用完全相同的库的二进制文件,或者更好的是,检查您引用的二进制文件是否带有绝对路径与您直接使用控制台时所指的完全相同。可以使用 locate 命令找到二进制文件,例如:

$locate python

确保您将引用的二进制文件与您在 shell 中调用的二进制文件完全相同,或者使用您计划放入 cronjob 的绝对路径在 shell 中再次测试。

另一个常见的问题来源是 cronjob 中的语法。请记住,您可以将特殊字符用于列表(逗号)、定义范围(破折号 -)、定义范围增量(斜杠)等。看看: http://www.softpanorama.org/Utilities/cron.shtml

【讨论】:

【参考方案5】:

如果您使用 sudo 运行某些命令,它将不允许。 Sudo 需要一个 tty。

【讨论】:

这也取决于sudo 配置。需要在无法提供密码的情况下运行的东西应该在您的sudoers 配置中配置为NOPASSWD:【参考方案6】:

在 Ubuntu 上,您可以启用 cron.log 文件以仅包含 CRON 条目。

取消注释/etc/rsyslog.d/50-default.conf 文件中提到cron 的行:

#  Default rules for rsyslog.
#

#                       For more information see rsyslog.conf(5) and /etc/rsyslog.conf

#
# First some standard log files.  Log by facility.
#
auth,authpriv.*                 /var/log/auth.log
*.*;auth,authpriv.none          -/var/log/syslog
#cron.*                          /var/log/cron.log

保存并关闭文件,然后重启rsyslog服务:

sudo systemctl restart rsyslog

您现在可以在其自己的文件中查看 cron 日志条目:

sudo tail -f /var/log/cron.log

示例输出:

Jul 18 07:05:01 machine-host-name CRON[13638]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)

但是,您不会看到有关在 /etc/cron.daily/etc/cron.hourly 中实际运行的脚本的更多信息,除非这些脚本直接输出到 cron.log(或者可能是其他日志文件)。

如果您想验证 crontab 是否正在运行并且不必在 cron.logsyslog 中搜索它,请创建一个将输出重定向到您选择的日志文件的 crontab - 类似于:

# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
30 2 * * 1 /usr/local/sbin/certbot-auto renew >> /var/log/le-renew.log 2>&1

步骤来自:https://www.cyberciti.biz/faq/howto-create-cron-log-file-to-log-crontab-logs-in-ubuntu-linux/

【讨论】:

Ubuntu 16.04 没有显示任何 cron 日志,这个信息起到了作用。【参考方案7】:

cron 已经通过邮件将它运行的每个作业的标准输出和标准错误发送给 cron 作业的所有者。

您可以在crontab 文件中使用MAILTO=recipient 将电子邮件发送到其他帐户。

为此,您需要让邮件正常工作。投递到本地邮箱通常不是问题(事实上,ls -l "$MAIL" 很有可能会表明您已经收到了一些邮件),但是将其从盒子中取出并发布到互联网上需要 MTA(Postfix、Sendmail 等)你)被正确配置以连接到世界。

如果没有输出,则不会生成电子邮件。

一种常见的安排是将输出重定向到文件,在这种情况下,cron 守护进程当然不会看到作业返回任何输出。一种变体是将标准输出重定向到文件(或编写脚本使其从不打印任何内容 - 也许它将结果存储在数据库中,或者执行根本不输出任何内容的维护任务?)并且仅在存在时接收电子邮件是一条错误消息。

要重定向两个输出流,语法是

42 17 * * * script >>stdout.log 2>>stderr.log

请注意我们如何追加 (double >>) 而不是覆盖,因此任何先前作业的输出都不会被下一个作业替换。

正如这里的许多答案所建议的那样,您可以将两个输出流发送到一个文件;用2>&1 替换第二个重定向,表示“标准错误应该去任何标准输出去的地方”。 (但我并不特别赞同这种做法。如果您对标准输出没有任何期望,但可能忽略了一些东西,可能来自从您的脚本调用的外部工具,这主要是有意义的。)

cron 作业在您的主目录中运行,因此任何相对文件名都应该是相对的。如果你想在你的主目录之外写,你显然需要单独确保你对该目标文件有写访问权。

一种常见的反模式是将所有内容重定向到 /dev/null(然后让 Stack Overflow 帮助您找出问题所在;但我们也看不到丢失的输出!)

在您的脚本中,确保将常规输出(实际结果,最好是机器可读的形式)和诊断(通常为人类阅读器格式化)分开。在 shell 脚本中,

echo "$results"  # regular results go to stdout
echo "$0: something went wrong" >&2

某些平台(例如 GNU Awk)允许您使用文件名 /dev/stderr 来显示错误消息,但这不适合移植;在 Perl 中,warndie 打印到标准错误;在 Python 中,写信给sys.stderr,或使用logging;在 Ruby 中,试试$stderr.puts。另请注意错误消息应如何包含生成诊断消息的脚本的名称。

【讨论】:

【参考方案8】:

如果您仍想检查您的 cron 作业,您应该提供一个有效的 在 cPanel 中设置 Cron 作业时的电子邮件帐户。

当您指定一个有效的电子邮件时,您将收到执行的 cron 作业的输出。因此,您将能够检查它并确保一切都已正确执行。请注意,如果 cron 作业命令没有输出,您将不会收到电子邮件。

请记住,对于每个已执行的 cron 作业,您都会收到一封电子邮件。如果您的 cron 运行过于频繁,这可能会淹没您的收件箱

【讨论】:

【参考方案9】:

使用命令crontab -e,然后将cron作业编辑为

* * * * * /path/file.sh > /pathToKeepLogs/logFileName.log 2>&1

这里,2>&1 表示标准错误 (2>) 被重定向到标准输出 (&1) 指向的同一文件描述符。

【讨论】:

以上是关于如何记录 cron 作业?的主要内容,如果未能解决你的问题,请参考以下文章

sh 有时候你想要运行一个自动的“git commit -a”(也许作为一个cron作业),但如果没有任何东西,你不想堵塞你的历史记录

Laravel 5.1 中的随机 cron 作业

如何在共享主机中为 Lumen 应用程序设置 cron 作业(使用 CPanel)?

Centos / Red Hat 服务器中 Cron 作业的退出代码存储在哪里?

在 Google Cloud DataProc 上安排 cron 作业

连接到同一数据库的两个cron作业会导致连接失败