Linux——crontab

Crontab介绍

   crontab是一个用于设置周期性被执行的任务工具,被周期性执行的任务我们称为Cron Job周期性执行的任务列表我们称为Cron Table。crontab命令常见于Unix和Linux的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。通常,crontab储存的指令被守护进程激活。crond 常常在后台运行,每一分钟检查是否有预定的作业需要执行。这类作业一般称为cron jobs。crontab命令的功能是在一定的时间间隔调度一些命令的执行。


  • 安装
[root@CentOS ~]# yum -y install vixie-cron
[root@CentOS ~]# yum -y install crontabs

说明
vixie-cron 软件包是 cron 的主程序;
crontabs 软件包是用来安装、卸装、或列举用来驱动 cron 守护进程的表格的程序。

  • 配置

cron 是 linux 的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务:

/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置
/sbin/service crond status //查看crontab服务状态

查看crontab服务是否已设置为开机启动,执行命令:

ntsysv

加入开机自动启动:

chkconfig –level 35 crond on

cron 的主配置文件是 /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

前四行是用来配置 cron 任务运行环境的变量。
SHELL 变量的值告诉系统要使用哪个 shell 环境(在这个例子里是 bash shell);
PATH 变量定义用来执行命令的路径。
cron 任务的输出被邮寄给 MAILTO 变量定义的用户名。
如果 MAILTO 变量被定义为空白字符串(MAILTO=“”),电子邮件就不会被寄出。
HOME 变量可以用来设置在执行命令或脚本时使用的主目录。

限制对 cron 的使用:

/etc/cron.allow和/etc/cron.deny 文件被用来限制对 cron 的使用。
这两个使用控制文件的格式都是每行一个用户。
两个文件都不允许空格。
如果使用控制文件被修改了,cron 守护进程(crond)不必被重启。
使用控制文件在每次用户添加或删除一项 cron 任务时都会被读取。
无论使用控制文件中的规定如何,root 都总是可以使用 cron。
如果 cron.allow 文件存在,只有其中列出的用户才被允许使用 cron,并且 cron.deny 文件会被忽略。
如果 cron.allow 文件不存在,所有在 cron.deny 中列出的用户都被禁止使用 cron。

  • crontab命令

–>图片说明

这里写图片描述

A 如何写crontab

功能:设置计时器。
语法:crontab[-u <用户名称>][配置文件] 或 crontab [-u <用户名称>][-elr]
解释:cron 是一个常驻服务,它提供计时器的功能,让用户在特定的时间得以执行预设的指令或程序。只要用户会编辑计时器的配置文件,就可以使 用计时器的功能。其配置文件格式如下:Minute Hour Day Month DayOFWeek Command

参数:
-e 编辑该用户的计时器设置。
-l 列出该用户的计时器设置。
-r 删除该用户的计时器设置。
-u<用户名称>  指定要设定计时器的用户名称。

格式:

*  *  *  * *  command
分 时 日 月 周  命令

第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令

demo:

*/1 * * * * root ab -n 2000 http://60.217.229.252/250k.jpg
上面例子表示每1分钟模拟用户访问http://60.217.229.252/250k.jpg 2000次

30 21 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启apache。

45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启apache。

10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启apache。

0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。

0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重启apache。

* */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启apache

* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
晚上11点到早上7点之间,每隔一小时重启apache

0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启apache

0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启apache

*/30 * * * * /usr/sbin/ntpdate 210.72.145.44
每半小时同步一下时间

每1分钟执行一次command
* * * * * command

每小时的第3和第15分钟执行
3,15 * * * * command

在上午8点到11点的第3和第15分钟执行
3,15 8-11 * * * command

每隔两天的上午8点到11点的第3和第15分钟执行
3,15 8-11 */2 * * command

每个星期一的上午8点到11点的第3和第15分钟执行
3,15 8-11 * * 1 command

每晚的21:30重启smb 
30 21 * * * /etc/init.d/smb restart


每月1、10、22日的4 : 45重启smb 
45 4 1,10,22 * * /etc/init.d/smb restart
......
B crontab注释

     在crontab中,#代表了注释,注释的存在,能够简化crontab的一些复杂操作。
     比如,如果有一个任务test.sh,每天都需要执行,每过10分钟执行一次,我们可以写成 */10 * * * * tesh.sh。现在有新要求,每天1点到1点10分不能执行,其余时间照旧。
     一种写法就是:将它拆成多条crontab,比如每天2点到0点执行,每天0点到1点执行,每天1点10分到2点执行。三条语句。这种方法的问题就是,如果再来新的要求呢,比如在此基础之上,每天8点到8点10分不能执行,这又怎么处理,写更多的crontab任务吗?
     另一种比较好的解决方案是:写一个run.sh脚本,每10分钟执行一次,首先判断当前时间是否是在1点到1点10分之间,如果不是,就执行tesh.sh,如果是,可以sleep10分钟。
     第三种非常好的方案就是利用注释。我们可以在1点时,将tesh.sh任务给注释掉,在1点10分,将tesh.sh任务的注释消除。要实现这种想法,需要使用sed命令。可以在crontab里面这样写:

#每隔10分钟执行一次  
*/10 * * * * tesh.sh  
  
#每天1点钟,将命令注释掉  
0 1 * * * sudo sed -i 's\%\*\/10\*\*\*\*tesh.sh\%#\1\%' /var/spool/cron/用户名  
  
#每天1点零10分,将被注释的命令恢复  
10 1 * * * sudo sed -i 's\%^##*\*\/10\*\*\*\*tesh.sh\%\2\%' /var/spool/cron/用户名 

     sed -i表示直接修改文件内容,之后的动作必须用单引号括上,单引号之后的是文件。单引号内部s表示替换,s之后的%是分隔符,代替默认的/分隔符,括弧表示将括号里面的内容保存下来,标记为1,#表示把注释扩展到下一个换行符以前,\1表示选取括号中的内容。
     这里出现了众多的反斜杠,都是用来做转义的,否则会被解析。
     其中%前面的反斜杠是用来转义crontab的,crontab中会将%解析成换行符。括弧和*前的反斜杠是因为sed会解析它们。
     如果不是在crontab中,这个命令可以写成 sed -i ‘s%*/10****tesh.sh%#\1%’ file

C crontab的调试方式

     如果crontab不执行,我们可以使用 sudo vim /var/spool/mail/用户名查看系统发给用户的mail,可以通过时间点,来找出执行失败的原因。

D /dev/null 2>&1 讲解

0 : 表示键盘输入(stdin)
1 : 表示标准输出(stdout),系统默认是1
2 : 表示错误输出(stderr)

command >/dev/null 2>&1 &  == command 1>/dev/null 2>&1 &

(1) command:表示shell命令或者为一个可执行程序
(2) >:表示重定向到哪里
(3) /dev/null:表示linux的空设备文件
(4) 2:表示标准错误输出
(5) &1:&表示等同于的意思,2>&1,表示2的输出重定向等于于1
(6) &:表示后台执行,即这条指令执行在后台运行

1>/dev/null : 表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,不显示任何信息。
2>&1 : 表示标准错误输出重定向等同于标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。

这条命令的意思就是在后台执行这个程序,并将错误输出2重定向到标准输出1,然后将标准输出1全部放到/dev/null文件,也就是清空.
所以可以看出" >/dev/null 2>&1 "常用来避免shell命令或者程序等运行中有内容输出。

附加 :(linux定时任务crontab如何实现每秒执行一次的方法)

(1)使用延时来实现每N秒执行

  • 创建一个php做执行动作,非常简单,就是把当前时间写入log。
<?php 
file_put_contents('/home/fdipzone/php/crontab/run.log', date('Y-m-d H:i:s')."\r\n", FILE_APPEND); 
?>
  • crontab -e 输入以下语句,然后 :wq 保存退出。
 - * * * * php /home/fdipzone/php/crontab/tolog.php 
 - * * * * sleep 10; php /home/fdipzone/php/crontab/tolog.php 
 - * * * * sleep 20; php /home/fdipzone/php/crontab/tolog.php 
 - * * * * sleep 30; php /home/fdipzone/php/crontab/tolog.php 
 - * * * * sleep 40; php /home/fdipzone/php/crontab/tolog.php 
 - * * * * sleep 50; php /home/fdipzone/php/crontab/tolog.php
  • 使用 tail -f 查看执行情况,可以见到log每10秒被写入一条记录。
tail -f /home/fdipzone/php/crontab/run.log 
2014-03-31 21:47:01 
2014-03-31 21:47:11 
2014-03-31 21:47:21 
2014-03-31 21:47:31 
2014-03-31 21:47:41 
2014-03-31 21:47:51 
2014-03-31 21:48:01

原理:通过延时方法 sleep N 来实现每N秒执行。
注意:

60必须能整除间隔的秒数(没有余数),例如间隔的秒数是2,4,6,10,12等。
如果间隔的秒数太少,例如2秒执行一次,这样就需要在crontab 加入60/2=30条语句。不建议使用此方法,可以使用下面介绍的第二种方法。

(2)编写shell脚本实现 推荐

#!/bin/bash 
step=2 #间隔的秒数,不能大于60 
for (( i = 0; i < 60; i=(i+step) )); do 
  $(php '/home/fdipzone/php/crontab/tolog.php') 
  sleep $step 
done 
exit 0
  • crontab -e 输入以下语句,然后:wq 保存退出。
# m h dom mon dow  command 
* * * * * /home/fdipzone/php/crontab/crontab.sh
  • 使用 tail -f 查看执行情况,可以见到log每2秒被写入一条记录。
~/php/crontab$ tail -f run.log 
2014-03-31 22:23:01 
2014-03-31 22:23:03 
2014-03-31 22:23:06 
2014-03-31 22:23:08 
2014-03-31 22:23:10 
2014-03-31 22:23:12 
2014-03-31 22:23:14 
2014-03-31 22:23:16 
2014-03-31 22:23:18 
2014-03-31 22:23:20 
2014-03-31 22:23:22 
2014-03-31 22:23:25 
2014-03-31 22:23:27 
2014-03-31 22:23:29 
2014-03-31 22:23:31 
2014-03-31 22:23:33 
2014-03-31 22:23:35 
2014-03-31 22:23:37 
2014-03-31 22:23:39 
2014-03-31 22:23:41 
2014-03-31 22:23:44 
2014-03-31 22:23:46 
2014-03-31 22:23:48 
2014-03-31 22:23:50 
2014-03-31 22:23:52 
2014-03-31 22:23:54 
2014-03-31 22:23:56 
2014-03-31 22:23:58 
2014-03-31 22:24:00

原理:在sh使用for语句实现循环指定秒数执行。

注意
如果60不能整除间隔的秒数,则需要调整执行的时间。例如需要每7秒执行一次,就需要找到7与60的最小公倍数,7与60的最小公倍数是420(即7分钟)。

则 crontab.sh step的值为7,循环结束条件i<420, crontab -e可以输入以下语句来实现

# m h dom mon dow  command 
*/7 * * * * /home/fdipzone/php/crontab/crontab.sh
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值