crontab 是 Linux 设置周期性定时任务的常用系统工具,本文列举一些实用的例子。
实例
这里是一些常用的例子:
一小时之内
描述 | cron 语法 | 例子 |
---|---|---|
每分钟执行 | * * * * * | 0:01,0:02,0:03,……23:59 |
每2分钟执行 | */2 * * * * | 0:00,0:02,0:04,……23:58 |
每小时的2分执行 | 2 * * * * | 0:02,1:02,2:02,3:02,……,23:02 |
每半小时执行 | */30 * * * * | 0:00,0:30,1:00,1:30,2:00,……,23:30 |
分钟是50分的倍数时执行 | */50 * * * * | 0:00,0:50,1:00,1:50,2:00,2:50,…… |
每17分钟执行 | 见 精细控制 一节 | 0:00,0:17,0:34,0:51,1:08,1:25,1:42, |
一天之内
描述 | cron 语法 | 例子 |
---|---|---|
每天整点执行 | 0 * * * * 或 @hourly | 0:00,2:00,3:00,……23:00 |
每小时的15分执行 | 15 * * * * | 0:15,2:15,3:15,……23:15 |
每天 12点5分 执行 | 5 12 * * * | 12:05 |
每天 10点到18点 整点执行 | 0 10-18 * * * | 10:00,11:00,12:00,……,18:00 |
每天 10点和18点 半点执行 | 30 10,18 * * * | 10:30,18:30 |
从0点开始,每隔4小时 半点执行 | 30 */4 * * * | 0:30,4:30,8:30,12:30,…… |
从1点开始,每隔4小时 半点执行 | 30 1-23/4 * * * | 1:30,5:30,9:30,13:30,…… |
一周之内
描述 | cron 语法 | 例子 |
---|---|---|
每周六中午12点执行 | 0 12 * * 6 或 0 12 * * sat | 每周六 12:00 |
每周二、四、六中午12点执行 | 0 12 * * 2-6/2 | 每周二、四、六 12:00 |
周末中午12点执行 | 0 12 * * sat,sun | 每周六、日 12:00 |
每周日的凌晨0点执行 | 0 0 * * 0 或 @weekly | 每周日 00:00 |
每周一、二 的 8点和12点执行 | 0 8,12 * * 1,2 | 每周一8:00,12:00,每周二8:00,12:00 |
一月之内
描述 | cron 语法 | 例子 |
---|---|---|
每月1日的凌晨0点执行 | 0 0 1 * * 或 @monthly | 每月1日 00:00 |
每月25日的17点执行 | 0 17 25 * * | 每月25日 17:00 |
每月的第一个周日执行 | 见 精细控制 一节 | 每月第一个周日 |
一年之内
描述 | cron 语法 | 例子 |
---|---|---|
每单数月份的25日的17点执行 | 0 17 25 */2 * | 1月25日 17:00,3月25日 17:00 |
crontab 的形式
系统中有两个crontab:
系统级别
系统级别的 crontab 有两种形式: /etc/crontab
文件和 /etc/cron.d
目录下的文件,只有管理员能修改。和下面用户级别的 crontab 不同的是,这两套文件随系统自动存在,而不像 用户级别 的 crontab 一样需要安装。系统级别的 crontab 中的命令前带有用户名,相比之下,更为安全、更常用的是用户级别的 crontab:
用户级别
每个用户默认是没有crontab的,初次执行 crontab
命令时,系统将为这位用户安装 crontab 文件,然后可以使用 crontab -e
编辑 或者 crontab -l
来显示 crontab 文件内容。
crontab 文件中合法的语句只有两类:
- 环境变量
- 定时任务
crontab 文件环境变量
在定时命令前设置环境变量,以保证命令的正确执行。格式为 name=value
SHELL
比如 crontab 默认使用的 shell 是 /bin/sh
,如果想设为 bash,需要像下面这样设置:
SHELL=/bin/bash
PATH
crontab 默认的 PATH
是 /usr/bin:/bin
,而不是用户登录后所看到的 PATH
变量,所以如果你不愿意使用绝对路径调用命令,而且命令也不在前面这两个
PATH 中,那么需要事先修改 PATH 变量:
PATH=/your/specific/path
容易出错的是,crontab 中不能像其他shell文件一样做变量替换,所以在 crontab 中下面的写法将达不到目的:
PATH=/your/specific/path:$PATH # 错误示范
一个例外是,bash 中可以使用波浪线(~)表示用户的主目录(在 /etc/passwd
中规定的):
SHELL=/bin/bash\
PATH=~/your/specific/path
HOME
命令被调起的起始路径,也就是 HOME
变量,是用户自己的主目录(在 /etc/passwd
中规定的)
MAILTO
当定时任务执行后,系统将给相关用户发站内邮件,如果不希望发出邮件,需要事先将 MAIL
命令定义为空值:
MAILTO=""
注意这里空值必须用引号表示,而不能只写一个等号
MAILTO= #错误示范
一个完整的例子
HOME=/home/yourname\
PATH=/home/yourname/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\
SHELL=/bin/bash\
MAILTO=""
1 * * * * command
crontab 时间语法
定时任务中有 6 个字段:分钟 小时 日期 月份 星期 命令
前五个字段表示时间条件,可能的取值为:
*
星号表示:每个、不要求、无所谓、随便、无论、任意值、全部值、所有值、总是、从第一个可能的值到最后一个可能的值:对于小时字段来说,*
等效于0-23
;对于星期字段来说,*
等效于0-6
;对于月份字段来说,*
等效于1-12
-
连字符表示范围(闭区间):比如1-4
等效于1,2,3,4
,
逗号表示:列表,可以列出所有希望的值,比如1,2,3,4
-,-
组合 逗号和连字符组合,比较容易理解:比如:8-12, 14-18
/
斜杠 表示 “从第一个值开始,每*个”,比如小时中的*/4
表示从0点开始的每4小时,1-7/4
等效于1,5
名称记法
月份和星期字段还可以使用名称的头三个字母来增强可读性(大小写均可),比如:jan,wed
预设周期
@yearly
命令于每年1月1日(无论星期几)的凌晨0点执行,等效于0 0 1 1 *
@monthly
命令于1日(无论几月、星期几)的凌晨0点执行, 等效于0 0 1 * *
@weekly
命令于星期日的凌晨0点执行,等效于0 0 * * 0
@daily
命令于每日的凌晨0点执行,等效0 0 * * *
@hourly
命令于每小时的0分执行,等效0 * * * *
日期和星期
如果日期和星期都有定义(非*号的值),那么将取 或 逻辑,只要满足任意一个条件即可执行。
crontab 命令格式
换行符%的转义
第六个字段是执行的命令,命令中的百分号(%)会被认为是换行符,百分号以前的部分是执行的命令,以后的部分会被当做标准输入。
如果命令中必须包含百分号,则需要用反斜杠(\)转义,不然百分号将不起作用。比如正常情况下 date
命令的执行格式是:
$ date "+%Y%m%d"
到了 crontab 里就要写成:
25 8 * * * date "+\%Y\%m\%d"
crontab 不工作的原因
如果 crontab 不工作,可以到 /var/log/syslog
中查看原因。一般会有如下可能:
PATH 变量错误
上节 提到, PATH
默认是最小集: /usr/bin:/bin
,和用户自己定义 shell 里的 PATH
变量不同,所以即使用户自己在 shell 中可以正确执行,也不说明 cron 一定能找到需要执行的命令。
解决方案:在命令之前指定 PATH
变量,参考 这里的例子
SHELL 的选择
上节 提到,SHELL 默认是 sh,所以如果一些命令只能在bash下执行,则需要预先设置 SHELL 变量
解决方案:在命令之前指定 SHELL
变量,参考 这里的例子
邮件服务
上节 提到,执行命令后需要发出邮件,一些系统中未预先安装邮件命令。如果从 /var/log/syslog
中看到是和邮件相关的报错,可以尝试下面的方法:
解决方案:安装邮件的相关工具:
# apt install mailutils
精细控制
crontab 的设计意图是精准的指定"(年,月,日,时,分)“的时间点坐标。
因为各种时间点坐标的进位周期各不相同(60分、24小时、30天、12月),所以一些只关注周期而忽略时间点坐标的需求,仅靠原生的 cron 语法就不能达到目的了。这时候,需要 test 命令配合完成,比如:
配合 test 使用
- 每月第二个周六
0 4 8-14 * * test $(date +\%u) -eq 6 && echo "第二个周六"
解释:test
命令用来检验参数是否为 true,当日期在每月的8日到14日之间时,每天执行 test
表达式,当 $(date +\%u)
结果等于 6 时,就能断定当天是当月的第二个周六。
- 每隔17分钟
每分钟检查当前的分钟数是否能被17整除
定时监控的例子
请看这篇: 监控 Jenkins agent 是否存活的脚本
如果您对本文有疑问或者寻求合作,欢迎 联系邮箱 。邮箱已到剪贴板
精彩评论
本站 是个人网站,采用 署名协议 CC-BY-NC 授权。
欢迎转载,请保留原文链接 https://www.lfhacks.com/tech/linux-cron/ ,且不得用于商业用途。