Aldebaran

人生最棒的感觉,就是你做到别人说你做不到的事。

0%

CronHowto

指原莉乃

Introduction

Cron是用于在指定时间执行所需任务(在后台)的系统守护程序。

crontab文件是一个简单的文本文件,其中包含一些在指定时间运行的命令列表。 它使用crontab命令编辑。 crontab文件中的命令(及其运行时间)由cron守护程序检查,cron守护程序在系统后台执行它们。

每个用户(包括root)都有一个crontab文件。 cron守护程序检查用户的crontab文件,无论用户是否实际登录到系统。

要显示crontab的在线帮助,请输入:

 man crontab

Starting to Use Cron

要将cron用于仅为当前的用户配置文件运行的任务,请将任务添加到自己的用户的crontab文件中。 要编辑crontab文件,请输入:

crontab -e

通常使用管理权限运行的命令(即通常使用sudo运行)可以将任务添加到root的crontab中。 要编辑根crontab,请输入:

 sudo crontab -e

Crontab Lines

crontab格式:

# Minute   Hour   Day of Month       Month          Day of Week        Command
# (0-59)  (0-23)     (1-31)    (1-12 or Jan-Dec)  (0-6 or Sun-Sat)
    0        2          12             *                *            /usr/bin/find

crontab每行由五个时间(time-and-date)字段,加上一个命令组成,以换行符(‘\ n’)结尾。
字段由空格分隔。 五个时间字段不能为空格,但是可以使用星号(*)代替,表示每个时间段(每个小时,每个工作日,每个月等)。
五个时间字段如下:分钟(0-59),小时(0-23,0 =午夜),日(1-31),月(1-12),工作日(0-6, 0 =星期日)。

例如

01 04 1 1 1 /usr/bin/somedirectory/somecommand
01 04 * * 1 /usr/bin/somedirectory/somecommand

逗号分隔值表示 在一段时间内的特定时间点运行特定命令的多个实例。 破折号(“ - “)分隔值可用于表示在连续时间段内运行命令。

01,31 04,05 1-15 1,6 * /usr/bin/somedirectory/somecommand

Cron还提供一些特殊的字符串,可以用来代替五个时间和字段:

string meaning
@reboot Run once, at startup.
@yearly Run once a year, “0 0 1 1 *”.
@annually (same as @yearly)
@monthly Run once a month, “0 0 1 * *”.
@weekly Run once a week, “0 0 * * 0”.
@daily Run once a day, “0 0 * * *”.
@midnight (same as @daily)
@hourly Run once an hour, “0 * * * *”.
@reboot /path/to/execuable1

上述示例将在系统重启的时候执行 /path/to/executable1。

更多信息,请输入

man 5 crontab

Crontab Options

-l 使当前crontab显示在标准输出上。
-r 删除当前crontab。
-e 使用当前EDITOR环境变量指定的编辑器(Vi,vim,nano)编辑当前crontab。

从编辑器退出后,Cron会检查修改后的crontab是否有错误,如果没有错误,则会自动保存到一个文件。 该文件存储在/var/spool/cron/crontabs中。

Allowing/Denying User-Level Cron

如果/etc/cron.allow文件存在,那么用户必须在文件其中列出才能被允许运行crontab命令。如果/etc/cron.allow文件不存在但是/etc/cron.deny文件,则用户不得列在/etc/cron.deny文件中,以便运行crontab。

在两个文件都不存在的情况下,当前Ubuntu(和Debian,但不是其他Linux和UNIX系统)的默认值是允许所有用户使用crontab运行作业。

在标准的Ubuntu安装中是不存在cron.allow或cron.deny文件,所以所有用户应该默认使用cron,直到创建其中一个文件。如果创建了一个空白的cron.deny文件,那将更改为其他操作系统的用户可能期望的标准行为:cron仅适用于root用户或cron.allow中的用户。

注意,如果你的用户名出现在/etc/passwd中,但是/etc/shadow中并没有,则crontab永远不会运行的。解决这个问题就是在/etc/shadow中为用户添加一个条目,其中包含*用于表示密码加密,例如:

joeuser:*:15169::::::

Further Considerations

Crontab命令通常会存储在属于你的用户的crontab文件中(并以该用户的权限级别执行计划任务)。 如果要定期运行需要具有管理员权限的命令,请编辑根crontab文件:

sudo crontab -e

根据正在运行的命令,你可能需要通过将以下行放在root的crontab文件的顶部来扩展root用户的PATH变量:

PATH=/usr/sbin:/usr/bin:/sbin:/bin

crontab -e使用EDITOR环境变量。 要将编辑器更改为您自己的选择,只需设置该变量。 你可能需要在.bashrc中设置EDITOR,因为许多命令使用此变量。 例如,为了将编辑器设置为nano(使用非常简单的编辑器)将此行添加到.bashrc中:

export EDITOR=nano

如果您的机器经常关闭,你可能还对at和anacron命令感兴趣,为安排的任务提供其他方法。
例如,anacron提供简单的系统范围目录,用于每小时,每天,每周和每月运行命令。 要在上述时间执行的脚本可以放在/etc/cron.hourly/,/etc/cron.daily/,/etc/cron.weekly/和/etc/cron.monthly/中。

Common Problems

crontab和cron作业运行都默认记录到/var/log/syslog,如果有问题,这是第一个检查是否没有按预期运行的地方。

如果用户在上次编辑crontab时不允许执行任务,只需将其添加到允许列表中即可。用户需要在添加到cron.allow之前重新编辑它们的crontab,然后才能运行它们的作业。

请注意,用户特定的crontabs(包括root crontab)在日期/时间字段之后不指定用户名。如果您不小心将用户名包含在用户特定的crontab中,系统将尝试以该用户名作为命令运行。

Cron作业可能无法与环境一起运行,尤其是PATH。如果您没有按照您的期望找到它们,尝试使用文件和程序的完整路径,。

“ % ”字符用作cron命令中的换行符分隔符。如果您需要将该角色传递到脚本中,则需要将其转义为“% ”。

Two Other Types of Crontab

上面讨论的crontab文件是用户crontab。 上述crontabs中的每一个都与一个用户相关联(包括root)。 还有另外两种类型的crontab,其语法如下:

minute(s) hour(s) day(s)_of_month month(s) day(s)_of_week user command

How Anacron is Set Up

在Ubuntu 9.10(可能在以后的版本)上,anacron似乎设置如下:

有一个Upstart任务,位于/etc/init/anacron.conf中,它运行/etc/anacrontab中的所有作业。它设置为在启动时运行。

有一个cron.d文件(/etc/cron.d/anacron)导致Upstart任务每天上午7:30启动。

有一个文件/etc/apm/event.d/anacron,当笔记本电脑插入A / C电源或唤醒时,会导致启动Upstart任务。

在系统crontab(/etc/crontab)中,如果anacron不可执行,run-parts将用于在cron.daily,cron.weekly和cron.monthly在6:25 AM,6:47 AM和6:52 AM。

在/etc/anacrontab中,run‑parts用于在anacron启动后5分钟运行cron.daily,每10分钟一次(每周一次)cron.weekly,每15分钟一次(每月一次)。

在cron.daily,每周和每月目录(/etc/cron.daily等)中,有一个0anacron文件设置anacron的时间戳,因此它将知道它们已经运行,即使它没有运行他们。

因此,每个启动,唤醒,插入(plug-in)和每天上午7:30都会出现anacron。看看各自的更改日志和打包数据库,看起来这个安装程序直接来自Debian,至少从2009年开始就没有更改。

Tips

crontab -e 默认是交互式操作,那么如果需要以非交互操作crontab:

生成一个临时文件,例如:/tmp/crontab.tmp
$ echo "0 5 * * 1 tar -zcf /var/backups/home.tgz /home" > /tmp/crontab.tmp

利用crontab命令加载/tmp/crontab.tmp

$ crontab /tmp/crontab.tmp

$ crontab -l
0 5 * * 1 tar -zcf /var/backups/home.tgz /home/

同样如果希望以非交互的方式修改crontab,又不希望使用管理员权限操作/var/spool/cron/crontabs下面的文件,则:

$ crontab -l > /tmp/crontab.tmp.1
$ sed -i "s/home/root/g" /tmp/crontab.tmp.1
$ crontab /tmp/crontab.tmp.1

crontab命令会校验语言,如果格式有误则会报错,例如

"/tmp/crontab.tmp.1":0: bad day-of-week

Examples

  1. 该行执行磁盘使用命令,在每月的1号到10号的每天凌晨2点获取根目录大小,并使用电子邮件将结果发送到指定的电子邮件地址。

     PATH=/usr/local/sbin:/usr/local/bin:/home/user1/bin
     MAILTO=user1@nowhere.org,user2@somewhere.org
     0 2 1-10 * * du -h --max-depth=1 /
    

Reference

Cron and Crontab usage and examples

CronHowto