一文详解 Linux 系统中的 Cron 任务

849 阅读6分钟

在 Linux 中的 cron 任务是一个强大的工具,它能够帮助用户执行一些定时任务。这一篇文章就是详细介绍 Linux 中的 cron,可以用它来帮助你自动化一些日常任务。

什么是 Cron

Cron 是 Linux 系统中的基于时间的任务调度器,也可以应用到其他的类 Linux 系统当中。它能够帮在固定的时间,日期或者间隔调度执行任务。比如,常见的系统维护,重要文件的备份等都可以使用 Cron 来完成

Cron 的工作原理

Cron 的核心组件是一个命名为 crond 的守护进程。它主要的任务就是在指定的时间间隔中检查,调度并且执行任务。这个守护进程会每分钟检查一次配置的 crontab filecrontab directory

这些 crontab filecrontab directorycron 任务调度系统的核心。其中,crontab(cron table) 指的就是在这些文件中包含的 cron 表达式列表。在这个 crontab file中的每一行都是一个定义好且在固定指定或间隔执行的任务

除了 crontab文件外,大部分的 Linux 系统包含一些列可被 cron 进程扫描的目录,如:*/etc/cron.hourly* , */etc/cron.weekly* , */etc/cron.monthly* 。这些目录的名字就表明了他们的调度时间,比如 /etc/cron.hourly下面脚本就是每小时执行一次

crontab 有两种类型:用户级别的和系统级别的。用户级别的 crontab文件是放在 /var/spool/cron目录下,而系统服务和应用级的的 crontab 文件是放在 etc/cron.d目录下面

Cron 的语法

一个 cron job 就是在 crontab file 中的一行。这一行由空格或者 tab分隔开的字段组成的,这一行的最后就是要执行的命令或者脚本。具体如下:

minute hour day_of_month month day_of_week command_to_execute

image.png

Minute(0-59)

这个字段指定了命令在那一分钟执行,比如:0 表示在每小时的开始执行

Hour(0-23)

这个字段指定了命令在哪个小时执行,比如:14 表示在下午两点执行

Day of Month(1-31)

这个字段指定了命令在哪一天执行。例如:1表示在这个月的第一天执行

Month(1-12)

这个字段指定了命令在哪个月执行。例如:3 表示命令在三月执行

Day of Week(0-6)

这个字段指定了命令在这一周的哪一天执行,0 表示周天。例如:5 表示每周五执行

特殊语法

除了上面的这些,还有一些特殊的值,比如:

  • *:表示每一次,比如:*Hour 字段表示每个小时
  • ,:逗号可以指定一个列表,比如:在字段 week 上 “1,3,4”表示周一,周三,周四执行
  • -:短横线指定一个范围,比如:在Hour上的 9-17,表示从早点九点到下午五点每个小时
  • /:这指定了一个增量,比如:在Minute上的 */10 表示每十分钟

除了这些以外,还有一些简单的字符表示时间和日期,如下:

  • @reboot:表示在启动时执行一次
  • @yearly,@annually:表示在每年一月一号12点执行,等同于 0 0 1 1 *
  • @monthly:在每个月一号中午12点执行,等同于 0 0 1 * *
  • @weekly:在每周周天中午12点执行,等同于 0 0 * * 0
  • @daily:每天中午12点执行,等同于 0 0 * * *
  • @hourly:每小时执行一次,等同于 0 * * * *

创建和管理

上面都是一些理论知识,下面我们来看下如何在 Linux 中创建和管理 cron 任务

创建用户级 cron job

创建的命令如下:

crontab -e

执行之后,会有一个选项列表,让你选择使用哪个编辑器来编辑,具体如下:

image.png

在选择了编辑之后,会打开一个文件,文件上面试一下指导创建 cron 任务的文档,我们现在在最下面添加任务:

0 3 * * * /home/xxx/backup.sh

我们添加了一个在每天三点执行的备份的任务,如下:

image.png

接着我们保存,然后退出。保存的时候会进行语法检查,保存退出之后就会生效,不需要重启系统。

注:上面的命令也可以编辑用户级的 cron 任务,编辑其他用户的可以使用:

sudo crontab -u bobby -e

创建系统级 cron job

命令 crontab -e是创建用户级的,创建系统级的 cron 任务可以直接编辑 /etc/crontab 文件,命令如下:

sudo vim /etc/crontab

下面我们添加一个任务删除 myservice 的日志,具体如下:

0  2  *  *  * root /usr/bin/find /var/log/myservice -type f -name '*.log' -delete

具体如下:

image.png

上面的 crontab 指定了 root,表示这个任务是在 root 用户下面执行。直接编辑 /etc/crontab 需要注意一些潜在的问题,

比如:

  • 这个方法不会进行语法检查,可以会增加错误风险
  • 因为这个文件会影响整个系统,不正确的任务可能会对整个系统的安全和稳定造成影响

所以,要谨慎使用

列出任务

使用下面的命令可以列出当前用户所有的 cron 任务:

cron -l

也可以列出其他用户的任务,如下:

sudo crontab -u xxx -l

系统级的任务可以使用如下命令:

sudo cat /etc/crontab

删除 Cron 任务

如果是删除单个任务,那么可以使用上面的 cron -e 进入编辑器,删除对应的条目即可。如果要删除这个用户的所有 cron 任务,可以使用如下命令:

crontab -r
故障排查

因为 cron 任务是无交互式在后台运行的,所以要留意潜在出现的错误,防止任务执行失败或者执行错误。首先,要检查 crontab 的定义是不是正确。接着要确保 crond 在后台运行,命令如下:

sudo systemctl status cron

正常运行的如下图所示:

image.png

接着,要确保在 crontab 表达式中指定的命令和脚本是否正确。检查用户是否有执行命令或者脚本的权限。除此之外,还要检查脚本的环境变量。因为 cron 不会自动继承用户或者系统的环境变量

Cron 任务和 Paths

当运行 cron任务的时候,它是在一个受限的环境当中,这意味着它并不继承用户或系统的环境变量。这有可能由于未定义或者错误的 path 导致任务执行失败。因此,需要在 crontab 文件中明确的设置 PATH 环境变量来解决路径的问题。用这个 PATH 告诉 crond 在那去找这个可执行文件,例如:

PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

crontab 文件的开头添加这一行,确保下面的所有 cron job 在这些目录下搜索可执行文件。

当然,为了保证文件的干净,最好还是指定可执行文件的全路径。还有就是,在保存之前,自己先在终端执行一下,保证能够正确执行。

结语

Cron 任务对于 Linux 的系统管理至关重要。他们对调度和自动化任务提供了一个健壮且通用的工具。

参考文档

man7.org/linux/man-p…

man7.org/linux/man-p…

linuxiac.com/how-to-use-…