用cron设置定时任务

Last Updated: 2023-06-01 09:23:38 Thursday

-- TOC --

cron(Command Run On)是Linux系统内置的定时执行任务的工具,本文总结如何使用它。

cron和crontab的区别

cron不是一个命令,它是一个daemon进程,用来控制已经设置好的定时任务的执行。一般Linux系统中都有它:

$ ps -A | grep cron
 336 ?        00:00:00 cron

Windows的WSL2系统就找不到cron!

也有的Linux系统使用crond这个进程名称。

而crontab就是一个命令,用来编辑定时任务。

cron的定时规则

┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday;
│ │ │ │ │                     7 is also Sunday on some systems)
│ │ │ │ │
│ │ │ │ │
* * * * *  command to execute

分、时、日、月、星

每一项需要定时执行的任务(command),都需要设定一个定时执行时间,前面的5颗星 *,就用来设定时间。这5个位置,不是一定都要填写,可以不填。

*   any value
,   value list separator
-   range of values
/   step values

举一些例子,通过例子学习:

# 在每个小时的第1分钟执行
1 * * * * echo "cs.pynote.net" >> trash.txt
# 每 10 分钟执行一次
*/10 * * * * echo "hello world" >> a.txt
# 每 2 小时执行一次
* */2 * * * echo "hello world" >> a.txt
# 每天 第3,4,5,6小时 各执行一次
* 3-6 * * * echo "hello world" >> a.txt
# 在每个星期 6 的 23 点 45 分执行
45 23 * * 6 /home/xinlin/test.sh
# 在每个月的1号执行
* * 1 * * /home/pi/python3 report.py
# 每月的2号和15号,HH:MM时间执行
mm hh 2,15 * * command
# 每个月的1号和15号,以及每个星期五,早上4:30分,执行
30 4 1,15 * 5 command

# 从每小时的20分开始,每15分钟执行一次
20/15 * * * *
# 在10点到20点的范围内,每隔2小时执行一次
* 10-20/2 * * *

可以看出定时任务执行时间的设置,是一种简单的时间匹配的规则。

5颗星是什么时间

以下两行定时任务的启动时间是一样的,都是每分钟的开始!

* * * * * command
*/1 * * * * command

* 表示 first-last,即全选,全匹配。

用5颗星来测试定时任务,一定要等到每分钟的开始,任务才会启动。而且,每分钟都启动一次,可能会造成相同任务的多任务情况。

按秒设定任务

按cron的时间规则,启动任务最小时间单位是分钟,如果希望按秒来启动任务,只能在任务内部自己用代码实现,cron本身不支持按秒启动任务。

crontab

按以上规则编辑定时任务,需要使用 crontab 命令。

usage:  crontab [-u user] file
        crontab [ -u user ] [ -i ] { -e | -l | -r }
                (default operation is replace, per 1003.2)
        -e      (edit user's crontab)
        -l      (list user's crontab)
        -r      (delete user's crontab)
        -i      (prompt before deleting user's crontab)

一般使用 crontab -e 来编辑,包括删除,用 crontab -l 来查看。

$ sudo crontab -e  # edit root's cron table
$ crontab -e       # edit current user's cron table

编辑的时候很简单,就像是用vim编辑一个文本文件(但是不用使用vim命令),只要按照上述格式要求来写即可,下图是我曾经编辑过的一个例子:

crontab-e

为了观察这些定时任务的执行情况,建议将所有输出和错误,都导入一个log文件!

另一种观察定时任务执行情况的方法,就是把执行时间设定在几分钟之后,等待几分钟,就能够看到执行的效果。确定执行没问题后,再将任务的启动时间修改为需要的时间。

cron避坑

以下都是我遇到国的在使用cron时的问题,希望你能够避免。

Permission denied

这应该是任务执行脚本没有可执行权限,启动时报错了。用 chmod +x 命令添加执行权限即可。

not found

检查任务脚本第一行的#!路径是否正确。

有的Linux是 #!/usr/bin/bash, 有的是 #!/bin/bash,有的两个路径都存在,指向一致!

以root执行cron任务

不要在定时任务的脚本中使用sudo,这可能会让任务停下来。(也许sudo免密的用户没问题,这个细节没测试)

使用 sudo crontab -e 编辑root用的定时任务。普通用户和root用户,或者每个用户,都拥有不一样的独立的cron table。

使用绝对路径

一般Linux系统默认路径都是用户的home路径,在cron定时任务中,如果是相对路径,就是从home路径开始。但有的时候,你会发现路径很混乱,OK,这个时候,最简单的方式,就是不要使用相对路径,使用绝对路径。

不仅仅是在cron table中使用绝对路径,你的任务脚本中也建议使用绝对路径,或者主动设定切换当前工作路径!

重启cron

前文介绍,cron是daemon进程,系统启动后就一直在后台运行。如果你修改了系统时间,或者修改了系统时区,记得一定重启cron进程!否则,定时任务的执行时间会不对。

重复进程

cron只负责启动任务,任务运行起来后,如果没有自己退出,又到了下一次启动的时刻,cron会毫不在意地再次启动进程,此时就会存在同一个任务的重复进程。这是否是个问题,如何解决等等,只能通过自己的任务代码来解决。

本文链接:https://cs.pynote.net/sf/linux/shell/202110035/

-- EOF --

-- MORE --