Linux设置定时任务:cron的用法

2023-07-01 15:53:46 浏览数 (2)

0x01.cron是什么

cron该词来源于希腊语chronos(χρόνος),原意是时间。是一款类Unix的操作系统下的基于时间的任务管理工具。用户可以通过cron在固定时间、间隔下,运行指定任务(可以是命令和脚本)。

cron的操作由crontabcron 表)文件驱动,该文件是一个配置文件,用于指定按给定计划定期运行的shell命令。crontab文件存储在保存作业列表和cron守护程序的其他指令的位置。 用户可以拥有自己的个人crontab文件,并且通常有一个系统范围的crontab文件(通常在/etc/etc的子目录中),只有系统管理员才能编辑。

要新添加一个定时任务,需要编辑crontab文件(即cron表),在其中添加相关任务即可,定时任务的编写规则见第三条。

0x02.crontab命令语法

代码语言:javascript复制
crontab [ -u user ] { -l | -r | -e }

说明:

  • -u user参数可以设定某一个用户的cron表,前提是必须要有相关权限(比如root权限),才能够设定其他人的crontab文件。如果不使用-u user的话,就是表示设定自己的crontab文件
  • -e:执行文字编辑器来设定时程表,内定的文字编辑器是vi
  • -r:删除目前的cron表中的所有任务
  • -l:列出目前cron表中的所有任务

综上,简单总结基本的常用命令:

直接编辑crontab文件:

代码语言:javascript复制
crontab
# 这个命令执行完之后,直接接受控制台中的输入流作为任务命令

用编辑器编辑crontab文件:

代码语言:javascript复制
crontab -e

删除当前所有的任务规则:

代码语言:javascript复制
crontab -r

列出目前所有的定时任务:

代码语言:javascript复制
crontab -l

其中,可以在crontab之后加上-u user的参数来操作指定用户对应的crontab文件,前提是必须要有相关权限(比如root权限)。否则就是操作自己的crontab文件。

0x03.crontab任务规则

1、标准规则

简单理解就是执行时间 命令的形式。

其中时间是由五个域组成,分别为分钟小时月份星期,每个域可以放置单一或多个数值,同时每个域之间都有空格来进行区分,如下所示:

代码语言:javascript复制
┌──────────── 分钟 (0 - 59)
│ ┌──────────── 小时 (0 - 23)
│ │ ┌──────────── 天 (1 - 31)
│ │ │ ┌──────────── 月份 (1 - 12)
│ │ │ │ ┌──────────── 星期中的某天 (0 - 6) (从周日开始算到周六)
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
* * * * * [用户名] <要执行的命令>

在用户层次的crontab文件中,用户名是可以省略的参数,而系统层次的crontabs文件的任务经常会指定一个或以上的用户进行执行,因此需要增加用户名字段。

注:

  1. 在某些系统里,星期日也可以为7
  2. 不很直观的用法:如果日期和星期同时被设定,那么当其中的一个条件被满足时,指令便会被执行。而不是同时满足
  3. 为方便个人记忆,前5个域可称之为分时日月周

表示时间的每个域里除了可以是具体数值,还可以是表达式或者是多个数值:

  • 逗号(,)列举出多个数值,例如:1,3,4,7 * * * * echo hello world表示在每小时的1、3、4、7分时,打印"hello world"。
  • 连词符(-)表示一个数值范围,例如:1-6 * * * * echo hello world ,表示每小时的1到6分钟内,每分钟都会打印"hello world"。
  • 星号(*)代表任何可能的值。例如:在“小时域”里的星号等同于“每一个小时”。
  • 百分号(%) 表示“每"。例如:* * * * * echo hello world表示,每10分钟打印一回"hello world"。 表格说明: 域 是否必填 允许的值 分钟 是 0–59 小时 是 0–23 天 是 1–31 月份 是 1–12、JAN–DEC 星期中的某天 是 0–6 、SUN–SAT
2、非标准规则

仅由某些cron程序的扩展版本支持,标准版本并不支持。以下这部分是在维基百科英文版本部分就着谷歌大概翻译出来的,如果有误,请以维基百科词条中的原文内容为准,词条链接在文末。

  • L:“L”代表“最后”。 当在星期字段中使用时,它允许指定诸如给定月份的“最后一个星期五”(“5L”)之类的构造。 在day-of-month字段中,它表示该月的最后一天。
  • W:'W' 字符允许用于日期字段。 此字符用于指定离给定日期最近的工作日(周一至周五)。 例如,如果将“15W”指定为day-of-month字段的值,则其含义为:“距该月的15日最近的工作日”。 因此,如果15号是星期六,触发器会在14号星期五触发。 如果15日是星期日,触发器会在16日星期一触发。 如果15号是星期二,那么它会在15号星期二触发。 但是,如果将“1W”指定为月份中的某天的值,并且第1天是星期六,则触发器会在第3天的星期一触发,因为它不会“跳过”一个月的天数边界。 仅当月中的某一天是一天,而不是天范围或天列表时,才可以指定“W”字符
  • #:'#' 允许用于星期字段,并且后面必须跟一个1到5之间的数字。 它允许指定诸如给定月份的“第二个星期五”之类的结构。 例如,在星期字段中输入5#3对应于每个月的第三个星期五
  • ?:用于代替“*``**”以将月中的某天或一周中的某天留空
  • /:用于表示跳过某些给定的数。例如,*/3在小时域中等于0,3,6,9,12,15,18,21等被3整除的数;
  • H:'H'表示替换了“散列”值。 因此不是一个固定的数字,例如表示每小时后的20分钟,表示该任务在一个未指定但不变的时间执行一次。 这允许随着时间的推移分散任务,而不是让所有任务同时开始并争夺资源。

0x04.其他

1、定时任务生效时间

需要注意的是,添加定时任务之后crontab需要等待几分钟才会生效,若要使立即生效需要重启cron服务:

代码语言:javascript复制
service cron restart
2、定时任务不生效

如果crontab定时任务不生效,可以排查以下几点:

1、Linux的时间与互联网时间不一致,而crontab中写的互联网时间

2、定时执行的.sh文件无执行权限

3、crontab进程未启动,crontab进程会每分钟去扫描/etc/crontab中的定时任务,故修改后无需重启该进程(重启只会让定时配置马上生效)

4、crontab进程配置文件中未指定具体执行用户

3、环境变量相关问题

在crontab文件中定义多个调度任务时,需要特别注意的一个问题就是环境变量的设置,因为我们手动执行某个脚本时,是在当前shell环境下进行的,程序能找到环境变量;而系统自动执行任务调度时,除了默认的环境,是不会加载任何其他环境变量的。因此就需要在crontab文件中指定任务运行所需的所有环境变量。

不要假定cron知道所需要的特殊环境,它其实并不知道。所以用户要保证在shell脚本中提供所有必要的路径和环境变量,除了一些自动设置的全局变量。以下三点需要注意:

脚本中涉及文件路径时写绝对路径;

脚本执行要用到环境变量时,通过source命令显式引入,例如:

代码语言:javascript复制
#!/bin/sh
  source  /etc/profile

当手动执行脚本没问题,但是crontab不执行时,可以尝试在crontab中直接引入环境变量解决问题,例如:

代码语言:javascript复制
* * * * * . /etc/profile; /xx/xx/test.sh

参考资料:

Linux crontab 命令 | 菜鸟教程 (runoob.com)

cron - Wikipedia

Cron - 维基百科,自由的百科全书 (wikipedia.org)

OpenWrt任务定时cron_hzlarm的博客-CSDN博客_openwrt 定时任务

0 人点赞