什么是例行性工作?比如太阳每天从东方升起,学校的上课铃总是不厌烦的定时响起,老妈的喊叫声总在每天的固定时刻叫你起床等。这些都是例行性工作。Linux系统也有自己的定时要办的事情,比如日志文件的轮替,whatis数据库的建立等等。
Linux例行性工作分一次性的(at)和循环执行的(cron),本篇博客探讨的就是循环执行的例行性工作。
它主要分为两类:
用户级
用户想要建立自己的循环性工作调度时,使用的命令是crontab。为了一些安全上的问题。我们通常限制可以使用这个命令的用户。如:
- /etc/cron.deny。我们将不能使用crontab命令的用户账号记录在这个文件中。
- /etc/cron.allow。我们将可以使用crontab命令的用户账号记录在这个文件中。
注意:往以上文件写内容时遵守一个账号一行的规则。
一般上面的两个文件我们只按一个来,系统默认保留的是/etc/cron.deny文件。
crontab命令
- crontab -e
编辑crontab的工作内容(编辑例行性工作)。执行此命令后会打开一个类似于vi编辑器的窗口,往里面写入自己的例行性工作,至于写入的格式下面会说。 - crontab -l
查阅crontab的工作内容,会显示出当前用户的所有crontab工作。 - crontab -r
删除所有的crontab工作内容,可以理解为清空。记住,当你仅仅要删除其中的一项时,不要使用此命令,用-e命令再次打开,重新编辑即可。 - crontab -u 用户名 [-e/-l/-r]
一般root用户会使用此命令,目的为帮助其他用户创建或删除crontab工作。
例如:
crontab -u lzk -e//帮用户lzk创建crontab工作
crontab内容格式
用-e命令打开并输入crontab工作内容,输入格式主要分6个字段。分为分钟,小时,日期,月份,周,命令,输入顺序自左向右,输入时每个字段中间用空格隔开。
字段“周”0或者7都表示星期天。
除了以上的六个字段外,有时还需要一些辅助字符。
- 星号“*”,就如正则表达式的星号一样。它表示适合所有的范围,任何时刻都接受。
22 * * 2 0 ls > /home/lzk/ls.txt //在2月份的每个周天的每个小时的22分钟都执行一次ls命令
- 逗号“,”,逗号表示分隔符。当一条命令在两个时刻都需要执行时,可以用逗号将其分开。
22,23 * * 2 0 ls > /home/lzk/ls.txt//在2月份的每个周天的每个小时的22和23分钟都分别执行一次ls命令
- 减号“-”,减号表示一段范围。例如:
22-29 * * 2 0 ls > /home/lzk/ls.txt//在2月份的每个周天的每个小时的22到29分钟内每分钟都分别执行一次ls命令,这个22-29表示“22,23,24,25,26,2728,29”。
- 斜线“/n”,这个不是换行符,n代表数字,表示每隔n隔单位,例如:
*/2 * * 2 0 ls > /home/lzk/ls.txt //在2月份的每个周天的每个小时每隔2分钟就执行一次ls命令,“*”与“/2”搭配,也可写成“0-59/2”。
示例
大家可能注意到我在上面的每条命令后都加了一个重定向符号‘>’和一个目录,目的是将ls命令执行后的内容重定向输入到文件/home/lzk/ls.txt中。
下面我们执行这个条命令:
* * * * * ls >> /home/lzk/ls.txt
5个星号代表无论上面时候,每分钟都执行一次ls命令。(可见最小单位为每分钟)
“>>”的意思是追加,不覆盖之前的内容,直接在文件尾写入。
执行crontab -e打开crontab,直接输入上述命令,然后保存退出(:wq)。
隔几分钟后,我们观察ls.txt文件,观察到的结果应该是将当前目录的ls结果重复输入了很多遍。
每个用户执行的crontab工作,系统都是有记录的。记录会保存在/var/spool/cron里面,每个用户对应一个文件。比如,刚才用户为“lzk”的我执行了一条crontab工作,此时/var/spool/cron里面就多了一个名字为lzk的文件,记录我的工作。
注意:不要使用vi/vim编辑器来编辑这个文件,可能由于输入语法的错误导致无法进行cron工作。
除了这个文件之外,cron执行的每一项工作都会记录在日志文件/var/log/cron中。
有很多,慢慢往下翻,你会找到自己的。
系统级
我们使用命令crontab来管理用户的例行性工作。而系统的例行性工作只需要编辑文件/etc/crontab文件即可。
(注意:这里指的是一个纯文本文件/etc/crontab。刚才我们执行的命令crontab也算是一个文件,它是/usr/bin/crontab可执行文件。注意区分两者。)
上面我们讨论过,cron工作的最小单位是分钟,所以cron每分钟就会读取一次/etc/cartab和/var/spool/cron文件的内容,所以只要你编辑保存好,系统便会自动执行。
有时处于某些原因或者系统设置,crontab被编辑好后,并不会马上执行。这时候需要重启crond服务。(/etc/init.d/crondrestart)
查看一下/etc/crontab文件的内容。
我们可以看到,此文件的前面多了几个环境变量。并且,在5个星号后面(命令前面)多了一个字段,用来表示指定的用户。我们刚才是在当前用户下执行crontab命令,所以不需要指定用户。现在是在系统下,所以需要指定用户去执行。
我们来看看这几个环境变量:
- SHELL=/bin/bash
表示当前运行环境为bash。 - PATH=/sbin:/bin:/usr/sbin:/usr/bin
表示可执行文件的查找路径。 - MAILTO=root
这个指定了当/etc/crontab这个文件中的例行性工作的命令发生错误时,或者该工作执行结果又stdout/stderr时,应该将错误信息或者屏幕显示的信息传给谁。系统默认是发一封e-mail给root。 - HOME表示工作目录。
输入命令示例:
保存退出后,你在root权限下输入crontab -l命令是看不到的。输入
crontab -u lzk -l才可以。或者切到lzk用户下执行crontab -l。
该指令执行结果与上述相同。
注意事项
使用例行性工作调度时我们应注意尽量避免多个工作在同一时间点进行。假如这多个工作同时进行且都非常消耗资源,那此时系统就会陷入繁忙的境地。注意将时间错开。
注意,周与日,月不能并存。我们不能指定了固定的日期又去指定固定的星期。