CRON-定时任务

简介

Linux中的定时任务用到的最多的,也是默认的程序就是CRON

ps aux | grep cron
systemctl status crond.service

CRON定时任务的最小单位是分钟,也就是最小只能1分钟执行1次,更小的定时任务可以用shell循环配合sleep命令来实现,如果不用定时任务提供的6位表达式工具来实现定时任务的服务,强行使用shell循环来实现,将会非常繁琐,比如要实现每个月1号执行1次的任务

另外一个比较流行的定时任务工具是Java语言用到的Quartz,这个使精确到秒级的

常用帮助

man cron
man crontab
info cron
info crontab

简单实操

[root@node1 ~]# crontab -e

[root@node1 ~]# crontab -l
# 注释信息
* * * * * date "+\%F \%T" &>> /tmp/cron-test.txt && df -h | fgrep "/home" &>> /tmp/cron-test.txt

[root@node1 ~]# tailf /var/log/cron
Feb 28 15:27:47 node1 crontab[4505]: (root) BEGIN EDIT (root)
Feb 28 15:27:52 node1 crontab[4505]: (root) REPLACE (root)
Feb 28 15:27:52 node1 crontab[4505]: (root) END EDIT (root)
Feb 28 15:28:01 node1 crond[2942]: (root) RELOAD (/var/spool/cron/root)
Feb 28 15:28:01 node1 CROND[4508]: (root) CMD (date "+%F %T" &>> /tmp/cron-test.txt && df -h | fgrep "/home" &>> /tmp/cron-test.txt)
Feb 28 15:29:01 node1 CROND[4536]: (root) CMD (date "+%F %T" &>> /tmp/cron-test.txt && df -h | fgrep "/home" &>> /tmp/cron-test.txt)
Feb 28 15:30:01 node1 CROND[4543]: (root) CMD (date "+%F %T" &>> /tmp/cron-test.txt && df -h | fgrep "/home" &>> /tmp/cron-test.txt)
Feb 28 15:30:01 node1 CROND[4547]: (root) CMD (/usr/lib64/sa/sa1 1 1)
....


[root@node1 ~]# cat /var/spool/cron/root
# 注释信息
* * * * * date "+\%F \%T" &>> /tmp/cron-test.txt && df -h | fgrep "/home" &>> /tmp/cron-test.txt

crontab

编辑,新增,删除定时任务规则,都是使用crontab命令

crontab -e 编辑定时任务规则(新增删除,# 开头是注释,一般会调用系统的vim编辑器来编辑)
crontab -l 列出定时任务

The time and date fields are:

        field          allowed values
        -----          --------------
        minute         0-59
        hour           0-23
        day of month   1-31
        month          1-12 (or names, see below)
        day of week    0-7 (0 or 7 is Sunday, or use names)

A  field  may  contain  an  asterisk  (*),  which  always  stands   for
"first-last".  * 代表所有

Ranges of numbers are allowed.  Ranges are two numbers separated with a
hyphen.  The specified range is inclusive.  For example, 8-11 for an (8点和11点也包含在内)

Lists are allowed.  A list is a set of numbers (or ranges) separated by
commas.  Examples: "1,2,5,9", "0-4,8-12".

"0-23/2"  OR "*/2"  specifying a job to be run every two hours


#run five minutes after midnight, every day
5 0 * * *
#run at 2:15pm on the first of every month
15 14 1 * * 

/var/spool/cron/  a  directory for  storing  crontabs  defined by users.

EXTENSIONS
       These special time specification "nicknames" which replace the  5  ini‐
       tial time and date fields, and are prefixed with the '@' character, are
       supported:

       @reboot    :    Run once after reboot.
       @yearly    :    Run once a year, ie.  "0 0 1 1 *".
       @annually  :    Run once a year, ie.  "0 0 1 1 *".
       @monthly   :    Run once a month, ie. "0 0 1 * *".
       @weekly    :    Run once a week, ie.  "0 0 * * 0".
       @daily     :    Run once a day, ie.   "0 0 * * *".
       @hourly    :    Run once an hour, ie. "0 * * * *".

 A "%" character in the command, unless
       escaped  with a backslash (\), will be changed into newline characters,
       and all data after the first % will be sent to the command as  standard
       input.

/etc/crontab

[root@node1 ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

CRON执行日志(/var/log/cron)

[root@node1 ~]# tailf  /var/log/cron
Feb 28 14:10:01 node1 CROND[4271]: (root) CMD (/usr/lib64/sa/sa1 1 1)
Feb 28 14:20:01 node1 CROND[4278]: (root) CMD (/usr/lib64/sa/sa1 1 1)
Feb 28 14:30:01 node1 CROND[4285]: (root) CMD (/usr/lib64/sa/sa1 1 1)
Feb 28 14:40:01 node1 CROND[4291]: (root) CMD (/usr/lib64/sa/sa1 1 1)
Feb 28 14:50:01 node1 CROND[4298]: (root) CMD (/usr/lib64/sa/sa1 1 1)
Feb 28 15:00:01 node1 CROND[4305]: (root) CMD (/usr/lib64/sa/sa1 1 1)
Feb 28 15:01:01 node1 CROND[4311]: (root) CMD (run-parts /etc/cron.hourly)
Feb 28 15:01:01 node1 run-parts(/etc/cron.hourly)[4311]: starting 0anacron
Feb 28 15:01:01 node1 run-parts(/etc/cron.hourly)[4320]: finished 0anacron
Feb 28 15:10:01 node1 CROND[4325]: (root) CMD (/usr/lib64/sa/sa1 1 1)

写定时任务的注意事项

  • 书写在CRONTAB里的定时任务,如果有输出内容或者报错,会被输出到系统内置的邮件中去,有可能造成磁盘空间无谓增大,因此我们尽可能自己控制输入,没用的内容输出到 /dev/null,需要保留的输出内容定位到文本文件里去,即可
  • 定时任务里的环境变量与在命令行敲命令的时候会有所不同,我们在shell测试好脚本运行无误后,最好要放到定时任务里再测一下,观察定时任务日志和输入结果,以确定符合预期
  • 如果提示找不到命令,可以尝试使用绝对路径,或者再定时任务的脚本里 source /etc/profile, 以及调试的时候打印 ${PATH} 以完全确定需要的执行命令路径正确
  • 对于文件的路径,最好使用绝对路径,也可尝试配合一些高级用法 workdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"; echo $workdir

常见报错

linux crontab 执行shell 打印不出结果怎么回事哈啊?
脚本进程只是继承了运行它的TTY。当手动运行它时,它会继承运行shell命令的TTY(终端)
对cron来说,甚至没有TTY。所以,没有TTY被继承。也就没有标准输入输出供使用,一般是重定向到文件来实现日志输出.
http://www.imooc.com/wenda/detail/585446

*/1 * * * * /usr/bin/docker exec dp-thrall-mysql bash /mysql-backup/mbak.sh &> /dev/null  正确能输出
*/1 * * * * /usr/bin/docker exec -it dp-thrall-mysql bash /mysql-backup/mbak.sh &> /dev/null  错误,无法使用

系统中全部CRON

/var/spool/cron/    
/etc/cron.d/        
/etc/cron.hourly/   
/etc/cron.daily/    
/etc/cron.weekly/   
/etc/cron.monthly/  
/etc/crontab        
/etc/anacrontab     
/etc/cron.deny    

在线CRON表达式生成器

https://tool.lu/crontab/ 这个支持的全面 重点推荐

https://qqe2.com/cron 这个网址只支持 Java 6位的 Quartz 定时任务表达式

http://www.bejson.com/othertools/cron/ quartz/Cron/Crontab表达式在线生成工具

https://crontab-generator.org/  

http://corntab.com/

6 Online Tools for Generating and Testing Cron Jobs for Linux
https://www.tecmint.com/online-cron-job-generator-and-tester-for-linux/

参考资料

Linux下的crontab定时执行任务命令详解
https://www.cnblogs.com/erbing/p/10019172.html

https://opensource.com/article/17/11/how-use-cron-linux

For more information, the man pages for cron, crontab, anacron, anacrontab, and run-parts all have excellent information and descriptions of how the cron system works.