2024年Cron任务完整指南

这是一份在 Linux 上创建、运行和调试 Cron 任务的完整指南。在这篇文章中,你将更深入地了解 cron 的基础知识,探索创建 Cron 任务的语法,以及如何使用 crontab 命令管理你的 Cron 任务。

2024年Cron任务完整指南

一、什么是 Cron 任务?

Cron 是一个 Linux 程序,允许用户安排一个软件片段的执行,通常以 shell 脚本或编译后的可执行文件的形式。当你有一个需要按固定时间表运行的任务或需要自动化重复任务(如下载文件或发送邮件)时,通常使用 Cron。

在最基本的层面上,Cron 任务是写入一个叫做 cron 表 的表中的条目,也简称为 crontab。这个条目包含一个调度和一个要执行的命令。cron 守护进程crond在 crontab 中寻找条目,以确定应该运行哪些作业,以及根据指定的调度何时运行它们。

注意:下面的示例在 Ubuntu 操作系统上运行。不同的 Linux OS 可能使用不同的包管理器,但所有其他命令都将以相同的方式工作。

二、Cron 任务是如何工作的?

大多数标准的 cron 安装包含两个命令:

  • croncrond,这是运行调度工具的守护进程
  • crontab,这是允许你编辑作业的 cron 条目的命令

当你从 Linux 的角度谈论一个 daemon(守护进程)时,它是一个在后台运行且非交互式的程序。这意味着该程序不接受任何用户输入,也不向用户显示输出。daemon 这个词历史上在 Unix/Linux 的环境中使用,并非在不同的操作系统中都是通用的术语。

守护进程将在 root 用户下运行。你可以运行以下命令来查看 cron 是否在运行:

    $ ps aux | grep cron

看到像这样的输出:

    root        617  0.0  0.0   9420  2800 ?        Ss   17:00   0:00 /usr/sbin/cron -f

如果你从命令中完全没有接收到任何输出,那么 cron 要么没有运行,要么没有安装。

在 Ubuntu 上,你可以通过运行以下命令快速安装 cron:

    $ sudo apt update && sudo apt install cron

如果你使用的不是 Ubuntu,你需要运行你的包管理器的等效命令。

一旦 cron 安装好了,记住要确保它已启用并正在使用 systemd 提供的 systemctl 命令运行:

    $ sudo systemctl enable cron

现在,Cron 应该已经在运行,如果你再次运行上面显示的 ps 命令,你应该能看到它。

三、Cron 任务调度语法

一个基本的 crontab 条目看起来像这样:

    *    *    *    *    *   /home/user/bin/somecommand.sh
    |    |    |    |    |            |
    |    |    |    |    |    要执行的命令或脚本
    |    |    |    |    |
    |    |    |    | 一周中的某天(0-6 | 周日-周六)
    |    |    |    |
    |    |    |  月份(1-12)
    |    |    |
    |    |  月中的某天(1-31)
    |    |
    |   小时(0-23)
    |
    分钟(0-59)

星号 (*) 匹配所有值,所以如果你看一下上面的例子,它指定 /home/user/bin/somecommand.sh 应在 分钟 0-59 和 小时 0-23 在 月中的某天 1-31 在 月份 1-12 在 一周中的某天 0-6 运行 – 或者换句话说 每分钟

Cron 条目也可以配置为在更复杂的时间运行。如果你想在周一至周五每天运行四次,你可以使用 步进操作符 ( / ) 和 范围操作符 ( )。

    0 */6 * * Mon-Fri /home/user/somejob.sh

该条目将在从午夜开始的每六个小时运行你的命令 – 即 12:00 a.m., 6:00 a.m., 12:00 p.m., 和 6:00 p.m. – 但只在周一至周五。

如果你想深入了解其他复杂的调度示例,crontab.guru 是一个用于测试调度语法并将它们翻译成简单英语的方便网站。

四、管理Crontab列表

一旦 cron 开始运行,它会每分钟检查以下文件中的 crontab 条目:

*   **/etc/crontab**
*   **/var/spool/cron/crontabs/$USER** (其中 `$USER` 是当前登录的用户)

第一个文件,/etc/crontab,是一个系统生成的文件,包含设计用于检查以下目录中的 cron 表条目的快捷命令:/etc/cron.hourly/etc/cron.daily/etc/cron.weekly,和/etc/cron.monthly

你可以通过使用 crontab 命令来实现这一点。从终端,使用以下命令进入你的用户的 crontab 的 编辑 模式:

    $ crontab -e

第一次运行这个命令时,操作系统应该会问你想使用哪个编辑器,会出现一个小菜单,像这样:

    no crontab for user - using an empty one

    Select an editor.  To change later, run 'select-editor'.
      1. /bin/nano      <---- easiest
      2. /usr/bin/vim.basic
      3. /usr/bin/vim.tiny
      4. /bin/ed

    Choose 1-4 [1]:

选择你喜欢的编辑器。如果你以前从未在 Linux 系统上使用过编辑器,那么就按照建议使用 nano,因为它大体上是一个易于使用的编辑器。

一旦你做出了选择,你选择的编辑器将打开你的用户的默认 crontab,像这样:

nano 编辑 crontab

目前,文件是空的,但你现在可以自由地在文件的底部添加一个 Cron 任务条目。

五、常见的 Cron 任务错误

到目前为止,你可能会有这样的印象,cron 似乎是一个相当强大的工具,使用它时不可能不出错任何有经验的系统管理员,如果他们花了一些时间设置 Cron 任务,都会告诉你,Cron 任务会并且确实经常失败,原因多种多样。

以下是你在设置 Cron 任务时可能遇到的一些问题的概述。

调度错误

如果你以前没有使用过它,很容易在 cron 语法中犯错误。也许你把语法的分钟和小时部分调换了位置。再次,你可以随时使用 crontab.guru 网站来验证你的语法是否正确。

环境变量

另一个常见的问题是,你的 shell 脚本在你从命令行运行时工作得很好,但似乎无法从 cron 条目运行。如果你的脚本调用了任何环境变量,这可能就是原因。Cron 不从 .bashrcbash_profile 这样的文件中加载变量,所以即使你指定了一个常见的变量,如 $USER,当 cron 守护进程运行你的作业条目时,该变量是未定义的。你需要要么硬编码你的变量值,要么手动从 .bashrc 这样的文件中加载值。

脚本可执行权限

默认情况下,当你创建一个 shell 脚本时,它没有 执行 权限:

    $ touch shell_script.sh
    $ ls -als *sh

输出:

    0 -rw-rw-r-- 1 user users 0 May 21 13:26 shell_script.sh

文件缺少执行权限。通过运行以下命令给文件赋予可执行权限:

    $ chmod +x shell_script.sh
    $ ls -als *sh

现在输出看起来像这样:

    0 -rwxrwxr-x 1 user users 0 May 21 13:26 shell_script.sh

这应该修复了 cron 需要的缺失的执行权限以便运行脚本。

了解更多linux文件权限的内容查看这篇文章Unix/Linux-文件权限/访问模式

磁盘空间

你的脚本可以非常强大,然而当系统资源耗尽时,任何强大的脚本都无法帮助你的 Cron 任务成功运行。不幸的是,防止这种情况的唯一方法是监控你的服务器,查看如可用磁盘空间、可用内存和充足的打开文件等指标。

任务重叠

你可能有一个 cron 条目,它运行的频率很高,并且在几秒钟内成功运行。为了方便讨论,也许你每分钟运行一次脚本。有可能一个外部变量干扰了作业的完成,导致作业需要超过一分钟才能完成。cron 守护进程会愉快地生成你的脚本的更多副本,直到你有一小部分军队,它们都在同时运行,从而消耗系统资源。你需要建立检查,如锁文件,以确保任何时候只有一个副本的脚本在运行。

外部变量

最后,外部变量是超出你控制范围的。例如,如果你有一个从 REST API 端点拉取信息的脚本,并且你正在查询的端点发生了变化,而没有通知你,你的 Cron 任务可能在你不知情的情况下失败。

六、监控 Cron 任务

Cron 任务可能以多种方式失败的方式后,你可能会想知道如何最好地监控它们。

让我们看一下你有哪些有用的选项来最好地监控你的 Cron 任务。

系统日志

Cron 自动有一些系统级别的日志记录。

在 Debian 和 Ubuntu 系统中,在 /var/log/syslog 中,cron 守护进程报告它何时开始或重新开始。在基于 Redhat 的系统中,cron 守护进程将同样的信息写入 /var/log/cron 的日志条目。

守护进程还报告它何时运行了你的作业,日志条目如下:

    Mar 29 16:00:01 mywebserver CRON[12624]: (user) CMD (/home/user/bin/check-visitors.sh)

不幸的是,cron 并不报告你的脚本的成功或失败。它甚至不能告诉你一个作业是否运行。

自定义度量

你可以直接将所有的测量逻辑写入从 cron 条目运行的脚本中。这将涉及到将事件记录到你自己的日志文件中,或者将你的脚本的退出状态捕获到另一个地方,以便由另一个过程监控。你也可以将任何发送到steddr的错误消息写入另一个错误日志文件。然而,这确实增加了你的脚本的复杂性,因为你需要考虑尽可能多的失败情况。

外部监控

幸运的是,有一个更简单的选项。是的,你可以通过确保你的每个脚本在出错时都能通知你,或者你可以将所有脚本的输出捕获到特殊的日志文件中。将任务执行的结果发送到IM系统中如飞书、钉钉等等。

Linux Dig命令详解
SSH的配置文件详解

发表我的评论

电子邮件地址不会被公开。 必填项已用*标注

20 + 21 =

ajax-loader