Linux中的定时任务crontab

时间:2021-02-08 08:01:31

        在Linux中,可以使用crontbab指定定时任务。

        使用命令crontab -e即可编辑crontab,在里面添加需要的定时任务。用户的定时任务文件为 /var/spool/cron/用户名 ,crontab -e命令将相当于vim /var/spool/cron/用户名。

1、如何写crontab

        crontab中每一行代表一个任务,每个任务由周期和任务名组成。如下形式   

59 23 10 5 2014 /home/root/tesh.sh
#分 时 日 月 年 |<-------命令串------->|
        表示2014年5月10日23点59分,执行/home/root下的tesh.sh脚本。

        时间周期中可以使用一些辅助字符,如:

        *    表示任何时刻都可以

        ,  若有多个时刻,用逗号分隔

        -     表示一个时刻到另一时刻之间的时间段

        /n   表示每过n个时间单位

        比如,*/10 3-6 10,11 * * /home/root/tesh.sh 就表示 每年每月的10号和11号,3点到6点之间,每过10分钟执行一次tesh.sh

2、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


3、crontab的调试方式

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


参考:

《鸟哥的linux私房菜-基础学习篇(第三版)》

http://www.2cto.com/os/201111/112217.html

http://syre.blogbus.com/logs/69798652.html

http://idealab.iteye.com/blog/825935

http://www.3lian.com/edu/2013/06-05/73527.html


————The End————