Linux定时循环执行任务crontab
参考:鸟哥的Linux私房菜 第16章
文章目录
应用场景还是比较广泛的,例如想每天凌晨4点备份一下数据库等等。
使用的是crontab
这个指令。
基本原理
实现原理就跟我们的备忘录差不多:系统存在一个定时任务备忘录。到了设定的时间,就会提醒系统该去执行备忘录上面的工作了。
比如有这样一个备忘录:
每小时的第30分钟休息一下
每天18:15去吃晚饭
每月7号12:00存钱
每年10月1号的00:00开始国庆节
每周4下午17:30去吃kfc疯狂星期四
到点以后,系统就会按照备忘录上的记录去完成任务
时间循环格式
基本格式
当然在linux系统中不能直接就像上面这样直接下达命令,需要使用特定的时间循环格式来描述上述工作。
可以拆分为:时间循环格式 + 命令行执行语句
比如正常执行命令可能是
echo "hello"
想每天早上8点循环执行下这个命令就是:
0 8 * * * echo "hello"
后面会详细讲解时间循环格式,为简便起见,在讲解的时候,我会把命令行执行语句的部分抽象一下。
对于上面那个备忘录
每小时的第30分钟休息一下
每天18:15去吃晚饭
每月7号12:00存钱
每年10月1号的00:00开始国庆节
每周4下午17:30去吃kfc疯狂星期四
按照时间循环格式翻译一下就是:
30 * * * * 休息一下
15 18 * * * 吃晚饭
0 12 7 * * 存钱
0 0 1 10 * 国庆节
30 17 * * 4 吃kfc
一共有5个位置可以控制循环的周期。分别为
分 时 日 月 周
比如上面例子第三条的
0 12 7 * * 存钱
就表示0分12时7号。转换一下意思就是每个月7号12:00去存钱。
比如上面例子最后一条的
30 17 * * 4 吃kfc
表示30分17时周四,转换一下就是每周四的17:00去吃kfc
周的用法:最后一个位置表示周几,1就是周一,4就是周四,0和7都表示周日
除此之外,还有一些其他的用法
分隔时段
每天9点整、12点整、18点整吃饭
使用逗号来分隔,格式为
0 9,12,18 * * * 吃饭
时间范围
周一到周五每天10点整上班
使用减号-
指定时间范围
0 10 * * 1-5 上班
间隔循环
每隔5分钟备份资料
使用斜线+数字的方式来使用间隔循环
*/5 * * * * 备份资料
上面的效果等同于
0-59/5 * * * * 备份资料
也可以就每个小时的前30分钟,每隔5分钟备份一下资料。
0-29/5 * * * * 备份资料
crontab命令
上面介绍了时间循环格式的基本写法,下面介绍如何把记录写到工作备忘录里。
主要掌握crontab几个参数的用法即可:
编辑工作内容
crontab -e
执行上述命令,会进入vim界面,此时只要在这个界面写入工作内容即可。比如之前提到的
30 * * * * 休息一下
15 18 * * * 吃晚饭
0 12 7 * * 存钱
0 0 1 10 * 国庆节
30 17 * * 4 双休
每一行就是一个工作命令。
上面写的还是抽象工作例子,正常可能是
30 * * * * /home/demo/rest.sh
15 18 * * * /home/demo/eat.sh
...
查看工作内容
crontab -l
清除工作内容
注意这个命令会删除所有的循环工作。慎用,只想删除一条或几条用crontab -e
就行了。
crontab -r
实际案例
由于我是用python的,这里用python举个例子
注意:用python执行脚本时,python的路径要写全,脚本的路径也要写全。
创建一个py文件,填入以下代码,把这个文件放到某个目录下,比如/home/demo/test.py
import os
import datetime
# 工作路径设定为这个脚本文件所在的位置,也就是/home/demo
os.chdir(os.path.dirname(os.path.abspath(__file__)))
with open('hello.txt', 'a', encoding='utf8') as f:
dt = datetime.datetime.now()
f.write(f"hello {dt}\n")
输入
crontab -e
添加一行
*/1 * * * * /opt/miniconda3/bin/python /home/demo/test.py
这样就会每分钟执行一下这个脚本,然后过一段时间,可以查看hello.txt
文件
hello 2022-03-10 15:13:01.509723
hello 2022-03-10 15:14:01.592939
hello 2022-03-10 15:15:01.699394
hello 2022-03-10 15:16:01.786072
hello 2022-03-10 15:17:01.892389
...
其他
上面的内容对于简单使用crontab命令来说已经足够用了,下面补充一点其他细节
权限控制
可以对crontab命令进行权限控制
在这个文件里,填写能够使用crontab命令的用户名。不在名单上的用户就不能用。
/etc/cron.allow
在这个文件里,填写不能使用crontab命令的用户名。在名单上的用户就不能用。
/etc/cron.deny
allow的优先级更高,但是一般用其中一个来做限制就行了。
均匀分配资源
假如我每五分钟都要备份一下数据库。我有4个数据库要备份,那就会同时挤到一块去执行,这时候可以使用分隔时段的方法规划一下。
1,6,11,16,21,26,31,36,41,46,51,56 * * * * 备份数据库1
2,7,12,17,22,27,32,37,42,47,52,57 * * * * 备份数据库2
3,8,13,18,23,28,33,38,43,48,53,58 * * * * 备份数据库3
4,9,14,19,24,29,34,39,44,49,54,59 * * * * 备份数据库4
周和日月不能同时共存
周和日月不能同时共存。why?反正不要一起写,执行的周期会和你预想的不一致。
比如你想每年的10月1号12:00,如果那天是星期5的话就去游泳。可能你会想这么写
0 12 1 10 5 游泳
这样的写法是错误的。