简单、严谨、安全 —— Dcron 简介

计划任务

在 UNIX 操做系统中,一般都有一个 crond 守护进程来按期执行设定好的计划任务,它能给服务器管理带来许多便利,同时能够大大节省管理员的时间和精力。好比,管理员但愿天天凌晨 3:00 对数据库进行一次备份,有了 crond 的帮助,管理员就没必要天天在睡得最香的时候起床了,crond 可以按照配置文件的指引自动完成这个任务。html

在GNU的世界里,最不缺少的就是选择,一样,这个 crond 也有多种不一样的实现,常见的有:fcron 、dcron 、vixie-cron 三种。本文将介绍其中的 dcron 实现,它的特色就是“简单、严谨、安全”。linux

Dcron

Dcron 3.2 版本之前是 Dillon 的做品,如今已经交给 Jim Pryor 维护,其主页是:http://www.jimpryor.net/linux/dcron.html数据库

Dcron 将全部任务都强制交给 /bin/sh 执行,也就是使用"/bin/sh -c"来运行任务。Dcron 不容许你在配置文件中指定环境变量或使用其它高级特性,这些事情最好放到脚本中去作。安全

Dcron 启动后首先扫描普通用户配置目录,寻找以/etc/passwd中用户名命名的文件,并将其做为该用户的配置文件。而后扫描root用户配置目录,并将其下全部文件都做为root用户的配置文件[笔者本人建议不要使用root配置目录,而是在普通用户配置目录中放置一个"root"文件,效果彻底相同]。[注意]配置目录下全部文件名含有句点(.)的文件和没法匹配用户名的文件都会被忽略。服务器

Dcron 在运行时会每分钟检查一次配置文件目录中的"cron.update"文件。你能够将已经被修改或删除的配置文件的名字(也就是用户名)添加到"cron.update"文件中(一行一个),这样就能够通知 Dcron 配置文件已经发生变化。不过,即便没有"cron.update"文件,Dcron 也会每小时自动从新扫描一次配置目录。函数

Dcron 有许多内置的限制以防止其被误用。其中最重要的是:每一个配置文件最大256行规则。每行规则最长1020字符。post

Dcron 并不使用 Sysklogd 记录日志,通常的方法是直接将命令的结果重定向到日志文件。spa

Dcron 的执行细节:它必须至少运行一个任务。它首先建立两个进程本身拥有的临时文件 O_EXCL 和 O_APPEND 存储全部输出,而后 fork() 出子进程并将其身份切换到该任务的属主,而后使用 exec 函数执行"/bin/sh -c"来运行任务,可是 O_EXCL 和 O_APPEND 始终由守护进程全部,以防止被用户恶意修改。任务完成后 crond 会校验没有安全防御的 mail 文件,若是它被新增了内容,那么就以任务属主的身份使用 sendmail 将修改过的 mail 文件发送给其属主。crond 不会在任务执行期间保持打开文件描述符,由于这样作可能会致使文件描述符被耗尽。crond 老是在每一分钟的开始时刻检查当前是否有事情可作,这种检查的效率很高,几乎不消耗任何 CPU 资源。操作系统

若是轮到某一条命令执行的时候,先前启动的命令还没有执行结束,那么将跳过这次执行。好比,若是设定每分钟执行一次"sleep 70",实际效果将是每两分钟执行一次。若是你不喜欢这样,能够在命令以后加上"&"转入后台执行,这样就不会受此影响了。.net

编译与安装

Dcron 是一个标准的 ANSI C 程序,理论上可使用任何符合标准的编译器进行编译(推荐使用 GCC)。但事实上,源代码中切换用户身份的操做是特定于Linux的方式,因此,只建议在Linux上编译和安装。

编译以前你须要详细阅读 Makefile 和 defs.h 文件,并根据你的须要进行修改。好比做者本人常常进行这样的修改:

sed -i -e's|/var/spool/cron/crontabs|/etc/crontabs|' -e's|/etc/cron.d|/share/empty|' defs.h

这个命令的做用是将配置文件的默认目录位置调整到"/etc/crontabs",并将root用户配置文件的默认目录位置调整到"/share/empty"。

而后使用下面的命令进行编译和安装:

make CFLAGS="$CFLAGS $LDFLAGS"
install -o 0 -g 0 -m 0500 crond   /bin/crond
chown 0:0  /etc/crontabs /share/empty
chmod 1700 /etc/crontabs /share/empty

请注意在安装时为 crond 及其配置目录设置的权限。

crond 一般在系统启动的时候由 /etc/rc.local 启动。在启动脚本中一般使用"-l8"指定日志等级。因为 Dcron 并不使用 Sysklogd 记录日志,因此通常直接将命令的结果重定向到日志文件。好比:

/bin/crond -l8 >> /var/log/crond.log 2>&1

命令行选项

语法

crond [-l#] [-d#] [-f] [-b] [-c directory] [-s directory]

选项说明

-l<日志等级>
设置日志等级(0-8),等级越低日志越详细,默认为"8"。
-d<调试等级>
设置调试等级,默认为"0"。使用这个选项会同时将日志等级设为"0",并致使 crond 做为前台进程运行。
-f
在前台运行
-b
在后台运行。这是默认值,除非你使用了 -d 选项。
-c 目录
指定配置文件目录,默认值是 /var/spool/cron/crontabs ,能够在 defs.h 文件中修改这个默认值[我通常修改为 /etc/crontabs]。
-s 目录
指定root用户配置文件目录,默认值是 /etc/cron.d ,能够在 defs.h 文件中修改这个默认值[我通常修改为 /etc/crontabs]。

配置文件语法

配置文件的格式与 vixie cron 相似,可是缺乏一些高级特性,好比不容许在配置文件中使用环境变量。

空白行以及以"#"开头的行将被忽略。

配置文件中的每一行都须要指定5个时间字段+1个命令字段,也就是:

分钟(0-59)  小时(0-23)  日(1-31)  月(jan-dec)  星期(sun-sat)   命令

每一个字段均可以指定一个范围(好比:feb-nov),或者逗号分隔的清单(好比:1,5,8,23),或者星号(*)表明所有。

月份和星期除了数字,还可使用字符串缩写,具体以下:
1-12月:jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec
周日-周六:sun,mon,tue,wed,thu,fri,sat

若是你同时指定了每周中的某一天和每个月中的某一天,那么二者同时有效,也就是这个任务会在每周的这一天执行,同时也在每个月的这一天执行。

下面是几个例子:

# 整年每分钟执行一次
*     *     *     *     *      /bin/false

# 天天上午 6:10 执行一次
10    6     *     *     *      date

# 每一年 4月2日 22:25 执行一次
25    22    2     apr     *       /bin/true

# 每周1、周2、周三 上午 2:00 6:00 11:00 22:00
# 或者 每个月4号 上午 2:00 6:00 11:00 22:00 执行一次
0     2,6,11,22    4     *       mon-wed    date >>/var/log/messages 2>&1

命令部分将使用

/bin/sh -c 命令

方式执行。

 

一般将命令的结果重定向到一个日志文件,不然默认将输出到 stdout 或 stderr ,而且同时使用sendmail发送到任务的属主。若是你但愿为某些特别的用户(好比 UUCP)利用这个sendmail机制,最好为这个用户设置一个别名以将邮件重定向到 root 或 postmaster 之类的用户。

相关文章
相关标签/搜索