浅谈计划任务管理工具crontab的用法

闾丘山
2023-12-01


  crontab 命令被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。
选项参数如下:

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

Linux下的任务调度分为两类:系统任务调度和用户计划任务调度。

  • 系统任务调度
    系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。
    /etc/crontab文件包括下面几行:
cat /etc/crontab 
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# 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

第一列单位为分,表示每时第几分钟,范围为0-59;
第二列单位为时,表示每天第几小时,范围为0-23;
第三列单位为日,表示每月第几天,范围为1-31;
第四列单位为月,表示每年第几月,范围为1-12;
第五列单位为星期,表示每星期第几天,范围0-7,0与7表示星期日,其他分别为星期1-6;

时间配置段类型
根据时间列中值的不同设置方式,可以总结出以下五种类型:

  • 固定某值,指定固定值,如指定1月1日0时0分执行任务
  * 0 0 1 1 * command
  月日时分都指定了固定数值。注:*在crontab中表示任意值都满足条件。
  • 列表值,时间值是一个列表,如指定一个月内2、12、22日零时执行任务
  0 0 2,12,22 * * command
  上述日指定多个值,2号、12号和22号,以逗号分隔;
  • 连续范围值,时间为连续范围的值,如指定每个月1至7号零时执行任务
0 0 1-7 * * command
上述日期为连续范围的值1-7时
  • 步长值,根据指定数值跳跃步长确定执行时间,如指定凌晨1时开始每割3个小时0分执行一次任务
  0 1-24/3 * * * command
  上述指定从凌晨1时每3个小时执行任务,如1点0分,4点0分,7点0分等。
  • 混合值,支持以上类型的组合,如指定每小时0至10分,22、33分以及0-60分钟每隔20分钟执行任务,如下
0-10,22,33,*/20 * * * * command
这里的分钟值采取了多种类型组合指定,包括连续范围值(0-7),列表值(22,33),步长值(*/20)。

系统的计划任务:

/etc/crontab        配置文件
/etc/cron.d/        配置文件
/etc/cron.hourly/   脚本
/etc/cron.daily/    脚本
/etc/cron.weekly/   脚本
/etc/cron.monthly/  脚本
@yearly 0 0 1 1 *
@annually  0 0 1 1 *
@monthly  0 0 1 * *
@weekly 0 0 * * 0
@daily  0 0 * * *
@hourly 0 * * * *
@reboot Run once after reboot

环境变量配置

环境变量配置这部分可以帮助我们减少去踩一些不必要的坑。简单说下涉及的环境变量。
SHELL为/bin/bash,表示使用/bin/bash解释执行命令
PATH表示到哪些目录路径寻找命令程序,此环境变量的值说明了为什么我们在crontab中执行命令时,尽量要写命令全路径才能执行的原因。
MAILTO变量作用是当任务执行有输出时,内容发送到哪个用户的邮箱。禁用可以设置MAILTO=""。
当我们在使用crontab时,发现某些定时任务不能顺利执行,但shell控制台执行成功,环境变量是否正确是我们需要首先关注的点之一。


用户计划任务调度

  • crontab命令定义每个用户都有专用的cron任务文件:/var/spool/cron/USERNAME
  • crontab命令:
crontab [-u user] [-l | -r | -e] [-i]
-l  列出所有任务
-e  编辑任务
-r  移除所有任务
-i  同-r一同使用,以交互式模式移除指定任务
-u user  仅root可运行,指定用户管理cron任务
  • 控制用户执行计划任务:/etc/cron.{allow,deny}

用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的crontab文件都被保存在/var/spool/cron目录中。其文件名与用户名一致,使用者权限文件如下:

/etc/cron.deny     该文件中所列用户不允许使用crontab命令
/etc/cron.allow    该文件中所列用户允许使用crontab命令
/var/spool/cron/   所有用户crontab文件存放的目录,以用户名命名

注意allow(白名单) 以及deny(黑名单)

  • 系统执行是先去找allow,如果有这个名单,就让名单上面的用户执行计划任务,不在名单上面的用户全部拒绝。
  • 如果没有allow,然后去找deny,如果有这个名单,那就先排除名单上面的用户不执行计划任务,如果这个文件都没有,所有用户都是白名单。

调试错误

  • 一是任务是否执行
    调试思路:首先,通过日志确认任务是否执行。然后,如未执行则分析定时语句。最后,定时没有问题,检查crond服务是否开启。下面说明具体分析步骤。调试错误,日志通常是个利器,crontab也有日志。日志文件位置为 /var/log/cron .
    日志中包含任务执行记录,配置错误提示,任务配置编辑重载记录,服务开启等记录。
    下面是日志的部分内容:

    Oct 26 20:51:01 Centos6 crond[1438]: (wall) ERROR (getpwnam() failed)
    Oct 26 20:52:01 Centos6 crond[1438]: (*system*) RELOAD (/etc/crontab)
    Oct 26 20:52:01 Centos6 CROND[2171]: (root) CMD ( wall echo "chenggongle  baba")
    
    

    对比日志记录,可以发现是因为计划任务没有指定用户来执行,所以错误,最后一条是我的修改够,执行成功的记录

  • 二看命令是否正确
    确认命令成功与否,这里总结步骤大致如下:
    获取命令执行输出,crontab中的命令执行出错,多数人都不知道如何调试。我们知道在控制台执行命令时,可通过输出获取错误信息调试问题。这种方式在crontab同样适用,方法就是利用重新向获取输出,进行分析。示例如下:

    * * * * * php /root/index.php >> /tmp/debug.log 2>&1
    

    这条任务总是执行失败,我们把输出重定向到/tmp/debug.log。查看debug.log,如下:

    $ cat /tmp/debug.log 
    /bin/sh: php: command not found
    /bin/sh: php: command not found
    

    显示php命令没有找到,很明显的可以确定是环境变量的问题。这种方式定位问题非常有效。


完 毕
 类似资料: