首页 > 编程笔记 > Linux笔记 阅读:8

Linux crontab命令:循环执行定时任务(非常详细)

at 命令仅可以在指定的时间执行一次任务,但是在实际工作中,系统的定时任务一般是需要重复执行的。这时 at 命令已经不够用了,我们就需要利用 crontab 命令来循环执行定时任务。

Linux crond服务管理与访问控制

crontab 命令需要 crond 服务支持。crond 服务同样是独立的服务,其启动和自启动方法如下:
[root@localhost ~]# systemctl restart crond   # 重新启动 crond 服务
[root@localhost ~]# systemctl enable crond    # 设定 crond 服务为开机自启动
crond 服务默认是自启动的。如果服务器上有循环执行的系统定时任务,就不要关闭 crond 服务。

crontab 命令和 at 命令类似,也是通过 /etc/cron.allow 和 /etc/cron.deny 文件来限制某些用户是否可以使用 crontab 命令的,而且原则也非常相似。
这个规则基本和 at 命令的规则一致,同样是 /etc/cron.allow 文件比 /etc/cron.deny 文件的优先级高,在 Linux 系统中默认只有 /etc/cron.deny 文件。

Linux用户的crontab设置

每个用户都可以实现自己的 crontab 定时任务,只需使用这个用户身份执行 crontab -e 命令即可。当然,这个用户不能写入 /etc/cron.deny 文件。

crontab 命令格式如下:
[root@localhost ~]# crontab [选项]
选项:
其实 crontab 定时任务非常简单,只需执行 crontab -e 命令,然后输入想要定时执行的任务即可。不过,当我们执行 crontab -e 命令时,打开的是一个空文件,而且操作方法和 Vim 的操作方法是一致的。这个文件的格式才是我们真正需要学习的内容,其格式如下:
[root@localhost ~]# crontab -e
# 进入 crontab 编辑界面,会打开 Vim 编辑你的定时任务。
***** 执行的任务
这个文件通过五个“*”来确定命令或任务的执行时间,五个“*”的具体含义,如下表所示。

表:crontab时间表示
项 目 含 义 范 围
第 1 个“*” 一小时当中的第几分钟 0~59
第 2 个“*” 一天当中的第几小时 0~23
第 3 个“*” 一个月当中的第几天 1~31
第 4 个“*” 一年当中的第几个月 1~12
第 5 个“*” 一周当中的星期几 0~7(0 和 7 都表示星期日)

在表示时间时,还有一些特殊符号需要学习,如下表所示。

表:表示时间的特殊符号
特殊符号 含 义
* 代表任意时间
, 代表不连续的时间,例如 08,12,16 表示 8、12、16 点各一次
- 代表连续的时间范围,例如 1-5 表示周一到周五
*/n 代表每隔 n 单位执行一次,例如 */10 表示每 10 分钟一次

当 crontab -e 命令编辑完成之后,一旦保存退出,这个定时任务实际就会写入 /var/spool/cron/ 目录,每个用户的定时任务使用自己的用户名进行区分。而且,crontab 命令只要保存就会生效,前提是 crond 服务是启动的。知道了这五个时间字段的含义后,我们多举几个时间的例子来熟悉一下时间字段,如下表所示。

表:crontab 举例
时 间 含 义
45 22 * * * 命令 每天 22:45 执行
0 17 * * 1 命令 每周一 17:00 执行
0 5 1,15 * * 命令 每月 1 日和 15 日 5:00 执行
40 4 * * 1-5 命令 周一到周五 4:40 执行
*/10 4 * * * 命令 每天 4 点起每 10 分钟执行一次
0 0 1,15 * 1 命令 每月 1、15 日及每周一 0:00 执行(不建议同时写日期和星期)

现在我们已经对这五个时间字段非常熟悉了,可是,在“执行的任务”字段中都可以写什么呢?既可以定时执行系统命令,也可以定时执行某个 shell 脚本。我们举几个实际的例子。

【实例 1】每 5 分钟向 /tmp/test.log 追加一行 “11”。
[root@localhost ~]# crontab -e
*/5 * * * * /usr/bin/echo "11" >> /tmp/test.log
虽然这个任务在时间工作中没有任何意义,但是可以很简单地验证我们的定时任务是否可以正常执行。如果觉得每隔五分钟太长,就换成“*”,让它每分钟执行一次。而且和at命令一样,如果我们定时执行的是系统命令,那么最好使用绝对路径。

【实例 2】每周二 5:05 重启系统。
[root@localhost ~]# crontab -e
5 5 * * 2 /sbin/shutdown -r now
如果服务器的负载压力比较大,就建议每周重启一次,让系统状态归零。例如,绝大多数游戏服务器每周维护一次,维护时最主要的工作就是重启,让系统状态归零。这时可以让我们的服务器自动来定时执行(在实际工作中,重启服务器有发生故障的可能,不建议进行定时任务自动重启,而是应该由管理员手工重启,并实时监控重启情况,此处只是举例)。

【实例 3】每月 1、10、15 日 3:30 执行日志备份脚本。
[root@localhost ~]# crontab -e
30 3 1,10,15 * * /root/sh/autobak.sh

这些定时任务在保存之后,就可以在指定的时间执行了。我们可以使用命令来查看和删除定时任务,具体如下:
[root@localhost ~]# crontab -l    # 查看当前用户任务
*/5 * * * * /usr/bin/echo "11" >> /tmp/test.log
5 5 * * 2 /sbin/shutdown -r now
30 3 1,10,15 * * /root/sh/autobak.sh

[root@localhost ~]# crontab -r    # 删除当前用户全部任务
[root@localhost ~]# crontab -l
no crontab for root
# 删除后,再查询就没有 root 用户的定时任务了
在书写 crontab 定时任务时,需要注意以下几个事项:

Linux系统的crontab设置

crontab -e 是每个用户都可以执行的命令,也就是说,不同的用户身份可以执行自己的定时任务。但是,有些定时任务需要系统执行,这时就需要编辑 /etc/crontab 这个配置文件了。

当然,并不是说写入 /etc/crontab 配置文件中的定时任务在执行时不需要用户身份,而是 crontab -e 命令在定义定时任务时,默认用户身份是当前登录用户。而在修改 /etc/crontab 配置文件时,定时任务的执行者身份是可以手工指定的。这样,定时任务的执行会更加灵活,修改起来也更加方便。

现在打开这个文件看看吧,具体如下:
[root@localhost ~]# vi /etc/crontab
SHELL=/bin/bash
# 标识使用哪种 shell
PATH=/sbin:/bin:/usr/sbin:/usr/bin
# 指定 PATH 环境变量。crontab 使用自己的 PATH,而不使用系统默认的 PATH,因此在定时任务中出现的命令最好使用绝对路径
MAILTO=root
# 如果有报错输出,或者命令结果有输出,就会向 root 发送信息
# For details see man 4 crontabs
# 提示大家可以在 “man 4 crontabs” 中查看帮助
# Example of job definition:
# — minute (0 - 59)
# |  — hour (0 - 23)
# |  |  — day of month (1 - 31)
# |  |  |  — month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  — day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
# 分 时 日 月 周 执行者身份 命令

只要按照格式修改 /etc/crontab 配置文件,系统定时任务就可以执行,例如:
[root@localhost ~]# mkdir cron
# 建立 /root/cron/ 目录
[root@localhost cron]# vi /root/cron/hello.sh
#!/bin/bash
echo "hello" >> /root/cron/hello.log
# 在 /root/cron/hello.log 文件中写入 “hello”
[root@localhost cron]# chmod 755 hello.sh
# 赋予执行权限

[root@localhost ~]# vi /etc/crontab
...省略部分输出...
* * * * * root /usr/bin/run-parts /root/cron/
# 让系统每分钟都执行一次 /root/cron/ 目录中的脚本,脚本执行者是 root 用户。
# 使用 run-parts 脚本调用并执行 /root/cron/ 目录中所有可执行文件。
只要保存 /etc/crontab 文件,这个定时任务就可以执行了,当然,要确定 crond 服务是运行的。/etc/crontab 文件可以调用 run-parts 脚本执行后续目录中的所有执行文件,这个 run-parts 其实是一个 shell 脚本,保存在 /usr/bin/run-parts 中,它的作用就是把其后面跟随的目录中的所有可执行文件依次执行。

为什么需要编写 run-parts 脚本?这是为了简化定时任务的书写。例如,我在 /root/cron/ 目录下拥有五个执行脚本,每个脚本都需要在相同的时间定时执行。如果手工指定定时任务,就需要写五条时间相同,只是执行的命令不同的定时任务。而如果使用 run-parts 脚本,就只需要一条定时任务即可完成。

需要注意的是,把五条命令放在一个目录下即可(我们会见到系统中部分定时任务是用 run-parts 脚本调用的,因此笔者举例说明)。

使用 /etc/crontab 文件执行的定时任务,不能通过 crontab -l 命令查询。

Linux /etc/cron.d/设置

在系统中,还有一个 /etc/cron.d/ 目录,这个目录中符合定时任务格式的文件也会执行。我们来看看这个目录中默认的文件:
[root@localhost ~]# ls /etc/cron.d/
0hourly  raid-check  sysstat
# 这个目录中默认拥有三个文件

在 /etc/cron.d/ 目录中默认有三个定时任务文件,查看 0hourly 文件的内容:
[root@localhost ~]# vi /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly
# 在每小时的 01 分钟,会使用 run-parts 脚本运行 /etc/cron.hourly/ 目录中的所有可执行文件
也就是说,我们完全可以写一个和 0hourly 文件类似的定时任务文件,放入 /etc/cron.d 目录。在这个目录中所有符合定时任务格式的文件,都会被定时任务调用执行。

Linux定时任务总结

通过学习,我们知道了定时任务有三种方法可以定制,还是比较复杂的。其实,对用户来说,他们并不需要知道这个定时任务到底是由哪个程序调用的。我们需要知道的事情是,如何使用系统的 crontab 设置。

对此,新老版本的 CentOS 没有区别,配置方法都有三种,分别是:
1) 第一种方法,用户直接执行 cronttab -e 命令编辑执行定时任务,这种方法最为简单直接。用户保存之后的定时任务会放置在 /var/spool/cron/下,使用以用户名命名的文件保存。

2) 第二种方法,修改 /etc/crontab 配置文件,加入自己的定时任务,不过需要注意指定脚本的执行者身份。建议在定义定时任务时都使用此种方法,方便管理、整理,并且不易遗忘。

3) 第三种方法,自己编写符合定时任务格式的文件,然后放入 /etc/crond/ 目录中,定时任务也可以执行。

这三种方法都是可以使用的,具体使用哪种全凭个人习惯。不过,要想修改 /etc/crontab 文件,必须是 root 用户才可以,普通用户不能修改,只能使用用户身份的 crontab 命令。

相关文章