一.关联命令及文件说明
crontab是很多Linux系统管理员都会用到的一种定期干活的工具,当然Linux操作系统自身也会偷偷的用它来做事情。正因为如此,写些文字来梳理下Administrator、crontab、OS三者之间的特殊关系(其实这个和三角恋并没有一毛钱的关系)。
1.1.Cron守护进程
CRON守护进程是随操作系统启动的crond service,主要用于执行那些需要定期执行的命令。它的启动方式有以下几种啦:
1).操作系统启动时自动启动(因为它在/etc/rc.d/init.d或/etc/init.d下嘛);
2).service crond start/stop....;
3).自己跑到/etc/rc.d/initd.或/etc/init.d下面去执行crond命令;
4).采用上面的方法
都不能传crond本身的参数(汗),不过你可以跑到/usr/sbin下面去找到它的真身crond程序来执行(可以传参哦,当然你也可以改/etc/init.d下面的启动脚本)
常规情况下用用(不改东西的情况下可以不传参数)就直接采用1.2.3方式好啦,至于想玩高级点嘛就要自己想办法咯。下面我们看看这个大众情人是怎么干活的:
1).首先呢crond这个守护进程会去/var/spool/cron目录下找以/etc/passwd中存在的用户名命名的文件并加载到内存中间来,同样也会加载/etc/anacrontab(
anacron详细说明会提到啦),/etc/cron.d目录下的文件;
2).然后每分钟去内存里面检查一遍看看是不是有需要执行的任务(勤劳的小蜜蜂,难怪大家这么喜欢它),执行完了以后呢可以通过邮件发送到crontab中MAILTO环境变量指定用户,如果
想要写日志也可以用-s实现哦;
我的脑子比较多事,想起了一个问题:"crond早早的把这一堆crontab加载到内存里面去了,那如果crontab更新了可怎么办呢?"。既然是守护进程且不会经常重启,开发者自然早就想到了咯,它是有两种办法来判断是否有更新的:
1).一种是通过inotify服务(一种监控文件系统事件的API)来监控所有的crontab文件(因为需要放哨,只要通过crontab编辑crontab文件,无论是否有内容更新都会去更新modtime,方便Inotify通报),当发现有变化的时候crond才会去读磁盘更新内存的内容。去/var/log/cron日志里面看看有没有类似内容就知道inotify是不是在为我们服务就好了((CRON) INFO (running with inotify support))。
特别注意:如果crontab文件是link的话则没有办法被inotify发现更新,这是此接口的限制,需要通过接收SIGHUP信号重新加载
2).第二种就是inotify不给crond服务的时候(无法初始化),这个时候呢crond就要亲力亲为了,每分钟都去看看crontab文件有没有更新。检查的文件列表如下:
/etc/anacrontab:需要定期调用的系统级别crontab;
/etc/cron.d/*:为不同用户定义的系统定期事件;
/var/spool/cron/*:用户自定义的crontab
问题又来了,在一些实行夏令时(Daylight Saving Time)的地方会不会有问题呢,因为需要在夏令时开始或者结束的时候去调时间。其实这个和我们时间跳变的情况也是一样的(小于3小时可以认为是夏令时),处理方式如下:
1).向前跳变小于3小时,如果任务的时间粒度大于1小时则就算调整过后已经过了执行时间任务也会立即执行,任务粒度小于1小时的就不会自动执行;(anacrontab又说不会执行,最好设计合理点)
2).向后跳变3小时,所有任务则需要特别干预防止重复执行;
3).任何超过3小时的时间调整,crond都会以新时间为准,不会对任务特别处理。
另外,RHEL的crontab支持通过PAM来控制crond的调度,有点高级以后再看。下面来看看/usr/sbin/crond命令的参数和用法:
crond [-n] [-p] [-s] [-i] [-m <mail command>] [-x [ext,sch,proc,pars,load,misc,test,bit]]
-s: 将JOB的输出通过syslog打印到系统日志,如果没有邮件服务器是有必要的;
-m: 将crond的输出作为后面mail command的标准输入用于邮件发送,如果-m 后面跟off则表示不通过邮件发送(这对MAILTO环境变量有屏蔽作用哦);
-n: 此参数会使crond改变配置在前台运行;
-p: (谨慎使用)允许用户设置的所有crontab,此参数可以屏蔽crontab必须是不可执行且不能被其他用户修改;
-x: debug flags;
注:当crond收到SIGHUP的时候会关闭并重新打开它的日志文件(方便日志的rotation),和syslog的日志没有关系
1.2.Crontab命令
1.1说了那么多cron守护进程怎么干活,那现在就看看怎么给这个大众情人分配任务吧。crontab命令粉墨登场,主要作用看这句:crontab - maintain crontab files for individual users。Crontab可以用来维护各个用户的cron table,非常不建议直接修改/var/spool/cron下面各个用户的table文件。如果需要限制哪些用户可以用,哪些用户不能用可以通过以下方式维护:
1).在/etc/下只存在cron.allow并在里面输入允许执行crontab命令的用户,则只有root和指定的用户可以使用crontab;
2).在/etc/下只存在cron.deny(默认就有)并在里面输入不允许使用crontab命令的用户,除这个用户以外的用户都可以使用crontab;
3).如果cron.allow和cron.deny都不存在则只有root用户可以执行crontab;
4).如果两个文件都存在则以cron.allow为准
crontab的临时目录可以在环境变量中设置,如果没有设置就是/tmp咯。下面说说crontab的语法(其实通常都是每个用户维护自己的crontab,就不说-u的事情了):
crontab [-u user] file
通过文件file来设定crontab
crontab [-u user] [-l | -r | -e] [-i] [-s]
-l: 显示当前的crontab;
-r: 删除当前的crontab;
-e: 编辑当前的crontab,退出后会自动加载;
-i: 删除前弹出提示信息;
-s: It will append the current SELinux security context string as an MLS_LEVEL setting to the crontab file before editing / replacement occurs - see the documentation of MLS_LEVEL in crontab(5).
1.3.cron table文件
您通过crontab命令下达给crond的全部指令都放在这些table里面了,主要就内容大体说明"在这一天的这个时候执行这个命令"。每个用户都有自己的cron table,执行这些cron tab中的命令时也是以该cron tab所有者的身份发起(如果命令里面就有su则实际干活的可能是另外一个用户)。特别说明:
1).空行和行首的空白会被忽略;
2).每条cron记录后不能跟注释;
3).环境变量后不能跟注释;
4).注释只能单独一行存在,上面两条用这一条替代不就好了么?
5).环境变量格式为:name=value,如果需要空格最好用引号(单双均可)将值括起来,SHELL,LOGNAME,HOME这几个环境变量会自动从/etc/passwd中去设定(如果crontab里面包含则会override 默认设定);
6).如果设定了邮件发送还会找MAILTO变量,如果没设定则发送到crontab所有者,如果设定为空则不发邮件
CRONTAB文件的有效执行部分每行的组成部分如下:
*(分) *(时) *(日) *(月) *(周) [User] Command
field allowed values
----- --------------
minute 0-59
hour 0-23
day of month 1-31
month 1-12 (or names, see below)
day of week 0-7 (0 or 7 is Sun, or use names)
Command
每个时间字段都有以下特性:
1).
* 表示任何时间;
2).
, 多个时间(或时间范围)之间用逗号隔开表示分隔,例如一个字段取1,3-5,20表示第1,3,4,5,20分钟的时候;
3).
- 表示时间范围,例如第一个字段21-30表示第21到30分的每分钟;
4).
/ 表示指定时间长度,例如第一个字段*/10表示每10分钟执行一次,3-50/2表示3-50分内每2分钟执行一次;
5).月日周几字段都可以用英文字母的前三位来代表;
6).day of month 和day of week两个字段可以同时生效,只要一个满足即会执行
7).时间字段可以用以下代号替代,对应关系如下:
@reboot : Run once after reboot.
@yearly : Run once a year, ie. "0 0 1 1 *".
@annually : Run once a year, ie. "0 0 1 1 *".
@monthly : Run once a month, ie. "0 0 1 * *".
@weekly : Run once a week, ie. "0 0 * * 0".
@daily : Run once a day, ie. "0 0 * * *".
@hourly : Run once an hour, ie. "0 * * * *".
命令及用户部分([User] Command):
1).因只有系统计划工作(anacron会讲到)才需要指定用户,每个用户自己的crontab无需维护此字段;
2).
命令中最好不要包含%,如果有必要则使用\进行转义,否则%后的内容会转换到新行作为标准输入给前半段命令
二.Crontab范例
2.1.EXAMPLE CRON FILE
# use /bin/sh to run commands, no matter what /etc/passwd says
SHELL=/bin/sh
# mail any output to ‘paul’, no matter whose crontab this is
MAILTO=paul
#
CRON_TZ=Japan
# run five minutes after midnight, every day
5 0 * * * $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
# run at 2:15pm on the first of every month -- output mailed to paul
15 14 1 * * $HOME/bin/monthly
# run at 10 pm on weekdays, annoy Joe
0 22 * * 1-5 mail -s "It’s 10pm" joe%Joe,%%Where are your kids?%
23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
5 4 * * sun echo "run at 5 after 4 every sunday"
2.2.Jobs in /etc/cron.d/
The jobs in cron.d are system jobs, which are used usually for more than one user. That’s the reason why is name of the user needed. MAILTO on the first line is optional.
2.3.EXAMPLE FOR JOB IN /etc/cron.d/job
#login as root
#create job with preferred editor (e.g. vim)
MAILTO=root
* * * * * root touch /tmp/file
2.4.SELinux with multi level security (MLS)
In crontab is important specified security level by crontab -s or specifying the required level on the first line of the crontab. Each level is specified in
/etc/selinux/targeted/seusers. For using crontab in MLS mode is really important:
- check/change actual role,
- set correct role for directory, which is used for input/output.
2.5.EXAMPLE FOR SELINUX MLS
# login as root
newrole -r sysadm_r
mkdir /tmp/SystemHigh
chcon -l SystemHigh /tmp/SystemHigh
crontab -e
# write in crontab file
MLS_LEVEL=SystemHigh
0-59 * * * * id -Z > /tmp/SystemHigh/crontest
When I log in as a normal user, it can’t work, because /tmp/SystemHigh is
higher than my level.
2.6.FILES
/etc/anacrontab system crontab file for jobs like cron.daily, weekly, monthly. /var/spool/cron/ usual place for storing users crontab. /etc/cron.d/ stored system crontables.
2.7.其他测试案例
11 20 * * * 每天的20:11分执行;
00 17 * * 3 每周三的17:00执行;
10,12 10 1 * * 每月1号的10:10和10:12分执行;
10-12 10 1 * * 每月1号的10:10,10:11,10:12分执行;
00 17 1 * 1 每周一及每个月1号的17:00都执行;
0,10,20,30,40,50 * * * * 每10分钟执行一次;
*/10 * * * * 每10分钟执行一次;
1 5-14/3 * * * 5:01,8:01,11:01,14:01执行