系统服务 配置工具
--------- ------ --------
|配置文件| ----------> |crond| <------------ |crontab|
-------- ------ --------
文件方式设置定时任务 每分钟都会从配置文件刷新定时任务 用于调整定时任务
Linux 下的任务调度分为两类:系统任务调度
和用户任务调度
。
系统任务调度
系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在 /etc
目录下有一个 crontab
文件,这个就是系统任务调度的配置文件。
通过直接编辑文件 /etc/crontab
可以设置系统级别的cron table。
[root@peipei3514 ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see 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
用户任务调度
用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab
工具来定制自己的计划任务。所有用户定义的 crontab
文件都被保存在 /var/spool/cron
目录中,其文件名与用户名一致。使用者权限文件如下:
/etc/cron.deny
该文件中所列用户不允许使用 crontab 命令;/etc/cron.allow
该文件中所列用户允许使用 crontab 命令,在CentOS7.2中不存在该文件。If the cron.allow file exists, a user must be listed in it to be allowed to use cron If the cron.allow file does not exist but the cron.deny file does exist, then a user must not be listed in the cron.deny file in order to use cron. If neither of these files exists, only the super user is allowed to use cron.
#####检查 cron 服务
crontab -l
,无错误则正常安装;service crond status
或 systemctl status crond
。注:Windows在运行中输入services.msc打开服务管理
[root@peipei3514 ~]# crond -h
Usage:
crond [options]
Options:
-h print this message
-i deamon runs without inotify support
-m off, or specify prefered client for sending mails
-n run in foreground
-p permit any crontab
-P use PATH="/usr/bin:/bin"
-c enable clustering support
-s log into syslog instead of sending mails
-x print debug information
Debugging flags are: ext,sch,proc,pars,load,misc,test,bit
通过以上帮助信息,我们可以知道 crond 是执行任务计划的一个守护进程。在使用 crontab 之前我们可以根据帮助信息来设置相关选项,一般情况下我们都使用默认值。
命令 crontab
用来设置、移除、列出服务 crond
表格,crond 服务的作用类似 atd,区别的地方在于 crond 可以设置任务多次执行。相对来说比 atd 更常用。
[root@peipei3514 ~]# crontab --help
crontab:无效选项 -- -
crontab: usage error: unrecognized option
Usage:
crontab [options] file
crontab [options]
crontab -n [hostname]
Options:
-u define user
-e edit user's crontab
-l list user's crontab
-r delete user's crontab
-i prompt before deleting
-n set host in cluster to run users' crontabs
-c get host in cluster to run users' crontabs
-s selinux context
-x enable debugging
Default operation is replace, per 1003.2
[root@peipei3514 ~]# man crontab
CRONTAB(1) User Commands CRONTAB(1)
NAME
crontab - maintains crontab files for individual users
SYNOPSIS
crontab [-u user] file
crontab [-u user] [-l | -r | -e] [-i] [-s]
crontab -n [ hostname ]
crontab -c
DESCRIPTION
Crontab is the program used to install a crontab table file, remove or list the existing tables used to serve the cron(8) daemon. Each user can have their own crontab, and though these are files in /var/spool/, they are
not intended to be edited directly. For SELinux in MLS mode, you can define more crontabs for each range. For more information, see selinux(8).
In this version of Cron it is possible to use a network-mounted shared /var/spool/cron across a cluster of hosts and specify that only one of the hosts should run the crontab jobs in the particular directory at any one
time. You may also use crontab(1) from any of these hosts to edit the same shared set of crontab files, and to set and query which host should run the crontab jobs.
选项 -e
表示编辑用户的 cron table。编辑时系统会选定默认编辑器,在笔者的环境中是 vim
。
使用 crontab -e
的方式编辑时,会在 /tmp
下面生成一个临时文件,保存后 crond 会将内容写入到 /var/spool/cron
下面一个和用户名同名的文件中,crond
会在保存时做语法检查。这也是推荐的设置定时任务的用法。
# 每隔3分钟测试10.0.1.252的连通性,并将结果追加输出到/root/252.log中
[root@peipei3514 ~]# crontab -e
*/3 * * * * /usr/bin/ping -c1 10.0.1.252 &>> /root/252.log
# 保存后会有crontab: installing new crontab字样出现。
# 注意六个部分都不能为空,命令最好写绝对路径,编辑普通用户的定时任务时,要注意命令的执行权限。
注:crontab [-u user] …. 编辑某个用户的 crontab 任务
/var/log/cron
文件保存着 cron 的任务执行记录。
[root@peipei3514 ~]# tail -f /var/log/cron
# 在.bash_profile中export一个APPDIR
[root@peipei3514 ~]# vim .bash_profile
APPDIR=/etc
export APPDIR
# 保存并退出
[root@peipei3514 ~]# source .bash_profile
[root@peipei3514 ~]# echo APPDIR
/etc
# 在crontab中打印APPDIR这个环境变量
[root@peipei3514 ~]# crontab -e
*/1 * * * * echo $APPDIR >> /tmp/appdir.log
# 保存退出
[root@peipei3514 ~]# tail -f /tmp/appdir.log
# 显示空行
# 因此crontab任务无法访问环境APPDIR变量
命令行双引号中使用%时,未加反斜线\
在 crontab 中 %
是有特殊含义的,表示换行的意思。如果要用的话必须进行转义,如经常用的 date ‘+%Y%m%d’
在 crontab 里是不会执行的,应该换成 date ‘+\%Y\%m\%d’
。
第三和第五个域之间执行的是 “或” 操作:四月的第一个星期日早晨1时59分运行a.sh
# 日期和星期是或操作,下面则表示1号-7号和四月中的星期日那天都会执行
59 1 1-7 4 0 /root/a.sh
# 利用shell命令判断是否是周日来执行脚本,注:这里%要用\转义
59 1 1-7 4 * test `date +\%w` -eq 0 && /root/a.sh
# 注:test的用法
[root@peipei3514 ~]# test 1 = 0 // 不能写成 test 1=0,否则结果为0,test把1=0当成字符串
[root@peipei3514 ~]# echo $?
1
# 或使用
[root@peipei3514 ~]# test 1 -eq 0
# 错误的设置,下面0时每一分钟都可以执行
* 0,2,4,6,8,10,12,14,16,18,20,22 * * * date
# 正确设置
0 */2 * * * date
# 先满足1-20约束,再满足每隔2分钟执行,即1 3 5 7 9 11 .. 19分执行date
1-20/2 * * * * date
Crontab 中最小只能设置到每分钟执行一个命令,如果想没半分钟执行某个命令怎么做到?
通过 shell 脚本的 sleep 命令配合 Crontab 即可完成这一功能
# 例如
date && sleep 30s && date
# 利用sleep休眠30s来延迟执行另一个cmd
[root@peipei3514 ~]# crontab -e
*/1 * * * * date >> /tmp/date.log
*/1 * * * * sleep 30s; date >> /tmp/date.log
通过 /etc/crontab
文件,我们可以清楚地看到每个字段的含义及取值范围,此处不再进行赘述。
特殊字符 | 含义 |
---|---|
*(星号) | 代表所有可能的值,只要其他值满足都执行,表示任何时候都匹配 |
,(逗号) | 用逗号隔开表示该字段取值。例如:”A,B,C” 表示A或者B或者C时执行命令 |
-(减号) | 两个可取值的整数之前的取值范围。例如:”A-B”表示A到B之间时执行命令 |
/n(斜杠) | 时间间隔频率。例如:”*/A”表示每隔A分钟(小时等)执行一次命令 |
/etc/crontab
文件直接配置。用户任务调度我们一般通过 crontab
命令来进行配置,用户任务调度的配置保存 /var/spool/cron/
目录下,并以用户名称命名。新创建的 cron job,不会马上执行,至少要过2分钟才执行。如果重启 crond 则马上执行。/etc/init.d/crond restart
解决问题。或者查看日志看某个 job 有没有执行h或者报错 tail -f /var/log/cron
。crontab -r
需要特别谨慎。它从 Crontab 目录(/var/spool/cron)中删除用户的 crontab 文件。删除了该用户的所有 crontab。30 21 * * * service httpd restart
45 4 1,10,22 * * service httpd restart
45 4 1-10 * * service httpd restart
*/2 * * * * service httpd restart
1-59/2 * * * * service httpd restart
#注:分钟不能为*,否则意思为晚上11点到早上7点之间,任何一分钟都可以重启apache
0 23-7/1 * * * service httpd restart
0,30 18-23 * * * service httpd restart
0-59/30 18-23 * * * service httpd restart
####定时任务不执行的问题
使用crontab时经常会遇到的一个问题是,在命令行下能够正常执行的命令或脚本,设置了定时任务时却不能正常执行。造成这种情况的原因一般是因为crond为命令或脚本设置了与登录shell不同的环境变量。
[root@peipei3514 ~]# head -3 /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
[root@peipei3514 ~]#
[root@peipei3514 ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@peipei3514 ~]#
这里 crond 的 PATH 和 shell 中的值不同,PATH环境变量定义了 shell 执行命令时搜索命令的路径。
对于系统级别的定时任务,这些任务更加重要,大部分 Linux 系统在 /etc 中包含了一系列与 cron 有关的子目录:/etc/cron.{hourly,daily,weekly,monthly}
,目录中的文件定义了每小时、每天、每周、每月需要运行的脚本,运行这些任务的精确时间在文件/etc/crontab中指定。如:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
对于24小时开机的服务器来说,这些任务的定期运行,保证了服务器的稳定性。但注意到这些任务的执行一般都在凌晨,对于经常需要关机的Linux计算机(如笔记本)来说,很可能在需要运行 cron 的时候处于关机状态,cron 得不到运行,时间长了会导致系统变慢。对于这样的系统,Linux引入了另一个工具 anacron
来负责执行系统定时任务。
anacron
的目的并不是完全替代 cron,是作为 cron 的一个补充。anacron 的任务定义在文件/etc/anacrontab
中:
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly
与cron是作为守护进程运行的不同,anacron是作为普通进程运行并终止的。对于定义的每个任务,anacron在系统启动后将会检查应当运行的任务,判断上一次运行到现在的时间是否超过了预定天数(/etc/anacrontab中任务行第一列),如果大于预定天数,则会延迟一个时间(/etc/anacrontab中任务行第二列)之后运行该任务。这样就保证了任务的执行。关于anacron的更多内容,请查阅相关文档。