Linux crontab是用来定期执行程序的命令。

一、介绍

1、crond 是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。

注意:新创建的 cron 任务,不会马上执行,至少要过 2分钟后才可以,当然你可以重启 cron 来马上执行。

2、linux 任务调度的工作主要分为以下两类:

  • a、系统执行的工作:系统周期性所要执行的工作,如备份系统数据、清理缓存
  • b、个人执行的工作:某个用户定期要做的工作,例如每隔10分钟检查邮件服务器是否有新信,这些工作可由每个用户自行设置,来定制自己的计划任务。

3、在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。/etc/crontab文件包括下面几行:

[root@localhost ~]# 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

前四行是用来配置crond任务运行的环境变量

第一行SHELL变量指定了系统要使用哪个shell,这里是bash

第二行PATH变量指定了系统执行命令的路径

第三行MAILTO变量指定了crond的任务执行信息将通过电子邮件发送给root用户,如果MAILTO变量的值为空,则表示不发送任务执行信息给用户

第四行的HOME变量指定了在执行命令或者脚本时使用的主目录。

二、用法说明

1.命令格式如下:

crontab [-u user] file

crontab [-u user] [ -e | -l | -r ]

  • -u user 是指设定指定 user 的时程表,这个前提是你必须要有其权限(比如说是 root)才能够指定他人的时程表。如果不使用 -u user 的话,就是表示设定自己的时程表。
  • -e : 执行文字编辑器来设定时程表,内定的文字编辑器是 VI
  • -r : 删除目前的时程表
  • -l : 列出目前的时程表

2.时间格式如下:

f1 f2 f3 f4 f5 program
如:* * * * * /bin/ls    #每一分钟执行一次 /bin/ls:
*    *    *    *    *
-    -    -    -    -
|    |    |    |    |
|    |    |    |    +----- 星期中星期几 (0 - 6) (星期天 为0)
|    |    |    +---------- 月份 (1 - 12)
|    |    +--------------- 一个月中的第几天 (1 - 31)
|    +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59)
  • 其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执行的程序。
  • 当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,其馀类推
  • 星号(*):代表所有可能的值,如month字段为星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
  • 逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
  • 中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
  • 正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。

三、常用命令

1.列出所有的crontab文件(查看定时任务列表):crontab -l
[root@localhost ~]# crontab -l
30 8 * * * sh /root/szx.sh szx
30 9 * * * sh /root/szx02.sh szx
2.关于crontab的编辑方式

除了crontab -e之外。还可以通过直接编辑/etc/crontab 的配置文件来实现

说明:系统级任务调度与用户级任务调度

root用户的任务调度操作可以通过“crontab –uroot –e”来设置,也可以将调度任务直接写入/etc/crontab文件,需要注意的是,如果要定义一个定时重启系统的任务,就必须将任务放到/etc/crontab文件,即使在root用户下创建一个定时重启系统的任务也是无效的。

四、crond服务

  • 安装crontab:yum install crontabs
  • centos7系统下服务可以通过systemctl来重启,systemctl restart crond
  • Linux下crontab服务对应的是crond服务。可以通过service crond restart重启
  • 查看crontab服务状态:service crond status

五、用法实例

1、每天上午八点半执行脚本szx.sh 进而控制docker容器szx

30 8 * * * sh /root/szx.sh szx

2、每天上午九点半执行脚本szx02.sh 进而控制docker容器szx

30 9 * * * sh /root/szx02.sh szx

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

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

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

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

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

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

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

10、每周六、周日的1 : 10重启smb
10 1 * * 6,0 /etc/init.d/smb restart

11、每天18 : 00至23 : 00之间每隔30分钟重启smb
0,30 18-23 * * * /etc/init.d/smb restart

12、每星期六的晚上11 : 00 pm重启smb
0 23 * * 6 /etc/init.d/smb restart

13、每一小时重启smb
* */1 * * * /etc/init.d/smb restart

14、晚上11点到早上7点之间,每隔一小时重启smb
* 23-7/1 * * * /etc/init.d/smb restart

15、每月的4号与每周一到周三的11点重启smb
0 11 4 * mon-wed /etc/init.d/smb restart

16、一月一号的4点重启smb
0 4 1 jan * /etc/init.d/smb restart

17、每小时执行/etc/cron.hourly目录内的脚本
01   *   *   *   *     root run-parts /etc/cron.hourly

说明:run-parts这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是目录名了

18、在 12 月内, 每天的早上 6 点到 12 点,每隔 3 个小时 0 分钟执行一次/usr/bin/backup:
0 6-12/3 * 12 * /usr/bin/backup

19、周一到周五每天下午 5:00 寄一封信给 [email protected]:
0 17 * * 1-5 mail -s "hi" [email protected] < /tmp/maildata

20、每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分....执行 echo "haha":
20 0-23/2 * * * echo "haha"

六、脚本无法执行问题

如果我们使用 crontab 来定时执行脚本,无法执行,但是如果直接通过命令(如:./test.sh)又可以正常执行,这主要是因为无法读取环境变量的原因。

解决方法:
  • 1、所有命令需要写成绝对路径形式,如: /usr/local/bin/docker。

  • 2、在 shell 脚本开头使用以下代码:

#!/bin/sh
. /etc/profile
. ~/.bash_profile
  • 3、在 /etc/crontab 中添加环境变量,在可执行命令之前添加命令 . /etc/profile;/bin/sh,使得环境变量生效,例如:
20 03 * * * . /etc/profile;/bin/sh /var/szx/run/test.sh

七、总结

1、注意事项
  • 当crontab突然失效时,可以尝试/etc/init.d/crond restart解决问题。或者查看日志看某个job有没有执行/报错tail -f /var/log/cron。
  • 千万别乱运行crontab-r。它从Crontab目录(/var/spool/cron)中删除用户的Crontab文件。删除了该用户的所有crontab都没了。
  • 在crontab中%是有特殊含义的,表示换行的意思。如果要用的话必须进行转义%,如经常用的date ‘+%Y%m%d’在crontab里是不会执行的,应该换成date ‘+%Y%m%d’
2、crontab箴言

1.环境变量问题,例如crontab不能识别Java的环境变量,crontab执行shell时,只能识别为数不多的环境变量,普通的环境变量是无法识别的,所以在编写shell时,最好使用export重新声明变量,确保脚本执行。

2.命令的执行最好用脚本

3.脚本权限加/bin/sh,规范路径/server/scripts

4.时间变量用反斜线转义,最好用脚本

5.定时任务添加注释

6.>/dev/null 2>&1 ==>&>/dev/null,别随意打印日志文件

7.定时任务里面的程序脚本尽量用全路径

8.避免不必要的程序以及命令输出

9.定时任务之前添加注释

10.打包到文件目录的上一级

04-28 21:23