Linux 系统 Crond 服务

Crond (Cron Daemon) 是类 Unix 系统中的一个守护进程,用于执行计划任务(定时任务)。它按照预定的时间表自动运行命令或脚本,无需人工干预。

相关文件路径:

  • 日志路径:
    • /var/log/cron (RHEL/CentOS)
    • /var/log/syslog (Debian/Ubuntu)
  • 邮件路径:/var/spool/mail/
  • 用户级的定时任务文件路径:/var/spool/cron/

1. Crond 定时任务的两种类型

1.1. 用户级定时任务

  • 通常由用户自己维护,系统管理员当然也可以维护。
  • 定时任务的配置最终都会记录到文件中,用户级的定时任务文件位于 /var/spool/cron/ 下,文件名是用户名。
  • 用户可以使用 crontab -e 命令来编辑自己的定时任务文件,使用 crontab -l 命令来列出自己的任务。
  • 用户级定时任务主要用于如:定时向互联网同步时间、定时备份系统配置文件、定时备份数据库的数据等场景。

用户级定时任务配置方式:

# 编辑当前用户的crontab
crontab -e
# 列出当前用户的crontab
crontab -l
# 删除当前用户的crontab
crontab -r
# 指定用户操作(需要root权限)
crontab -u username -e

# /etc/cron.deny 是定时任务的黑名单,使用root将需要拒绝的用户加入/etc/cron.deny
echo "username" >> /etc/cron.deny 
# 登陆该普通用户则无法编写定时任务
Bash

1.1. 系统级定时任务

  • 只有系统管理员可以编辑。
  • 系统级定时任务文件位于 /etc 目录下,文件名有 crontab、cron.d/、cron.daily/、cron.hourly/、cron.monthly/ 及 cron.weekly/。
    • /etc/crontab:这是主 crontab 文件,包含了系统任务表,以及在预设时间执行的工作。
    • /etc/cron.d/:此目录存放任何想被 cron 守护进程执行的任务。
    • /etc/cron.daily/:此目录下存放的任务脚本会被系统安排在每天凌晨执行。
    • /etc/cron.hourly/:此目录下存放的任务脚本会被系统安排每小时执行一次。
    • /etc/cron.monthly/:此目录下存放的任务脚本会被系统安排在每月的某一天执行。
    • /etc/cron.weekly/:此目录下的任务脚本会被系统安排在每周的某一天执行。
  • 系统级定时任务主要用于如:临时文件清理例 /tmp 和 /var/tmp 等、系统信息采集、日志文件切割等场景。
  • 系统级定时任务需要指定用户名,如:0 * * * * root /usr/bin/backup.sh。

系统级定时任务配置方式:

# 方式一:编辑文件/etc/crontab,添加定时任务。
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

# 示例:
0 * * * * root /usr/bin/backup.sh
# 修改后无需重启crond,会自动重新加载。
# 适用于需要指定运行用户的系统级任务。


# 方式二:在 /etc/cron.d/ 目录下增加定时任务配置文件,每个文件对应一组任务。
# 示例:
vim /etc/cron.d/clean-tmp
0 3 * * * root /usr/bin/clean-tmp-files.sh

# 方式三:将需要周期运行的脚本放在 cron.daily/、cron.hourly/、cron.monthly/、cron.weekly/ 等目录下。
# 示例:每周运行一次 clean-tmp-files.sh 脚本
ls /etc/cron.weekly/
clean-tmp-files.sh
# 注意给脚本添加可执行权限
chmod +x /etc/cron.weekly/clean-tmp-files.sh
Bash

2. Crontab 文件格式

Crontab 文件中的每一行代表一个任务,格式如下:

* * * * * command-to-be-executed
    
    └── 星期几 (0 - 6) (0表示星期日)
   └──── 月份 (1 - 12)
  └──────  (1 - 31)
 └──────── 小时 (0 - 23)
└────────── 分钟 (0 - 59)

# *:匹配所有有效值
* 3 * * * /root/scripts/backup.sh  # 在每天 3:00-3:59 期间每分钟执行备份脚本
0 3 * * * /root/scripts/backup.sh  # 每天凌晨3点执行备份脚本
# ,:指定多个值(如"1,3,5")
0 1,3,5 * * * /root/scripts/backup.sh  # 每天凌晨1、3、5点执行备份脚本
# -:指定范围(如"1-5")
0 1-5 * * * /usr/bin/monitor_system.sh  # 每天凌晨1-5点每小时执行备份脚本
# /:指定间隔频率(如"*/2"表示每两单位)
*/5 * * * * /usr/bin/monitor_system.sh  # 每5分钟检查一次系统状态
Bash

3. Crontab 不执行的解决办法

第一,脚本代码有问题,解决:先手动调试跑通
 
第二,执行环境问题:手动执行成功而crontab不能执行的时候,很可能就是执行环境的问题,例如相关路径的设置问题,可以在代码最前面执行 source /home/user/.bash_profile
 
第三,系统时间不正确。这种问题最好理解,也是比较常见和隐蔽的问题,解决方案:date -s ********
 
第四,就是我们的脚本是否有可执行权限。必须保证执行脚本的用户有执行改文件的权限。
 
第五,crontab 守护进程死掉了。这种情况是极少发生的,但也不排除,当我们实在是找不到其他原因的时候可以用。解决方案:重启该进程。
 
第六,crontab不执行的问题困扰了好长时间,脚本写的都正确,但是就是不执行,最终解决方法如下:
crontab -u root /var/spool/cron/root
这样root用户的crontab就生效了
[root@localhost ~]# systemctl restart crond
重启下服务就好了
 
第七,crond没有启动
 
第八,脚本编码问题,脚本在window下编写,传到linux下后报“锘?!/bin/bash”,用vi编辑器新建新shell脚本,输入内容后保存。
 
第九:特殊符号无法识别,需要添加转义
 
* * * * * tar czf /tmp/`date '+%Y'` /etc 该计划任务中命令的执行流程是crond->tar命令,而crond在执行tar命令时,无法识别通配符%的意思(shell能识别),所以该命令无法正常执行
 
解决方案一:添加转义符号
* * * * * tar czf /tmp/`date '+\%Y'` /etc
 
解决方案二:直接将命令扔到脚本里
通常都会把要执行的操作放到文件中,然后/bin/bash a.sh去执行,* * * * * /bin/bash a.sh  ,这样的执行流程就变成了crond->bash shell->a.sh,这样a.sh内即便是写%号,也能被识别出来
Bash

4. Crontab 定时任务编写注意点

  • 定时任务规则之前加注释。
  • 使用脚本执行定时任务 (只有一条简单命令的可以直接使用命令执行)。
  • 运行脚本一定要用绝对路径执行,并且最好统一脚本位置。
  • 定时任中 date 命令的百分号需转义才能使用。
    • * * * * echo date "+%F" >> /tmp/1.log # 无法执行
    • * * * * echo date "+\%Y_\%m_\%d \%H:\%M:\%S" >> /tmp/2.log # 可以执行
  • 命令或脚本结果 (正确及错误) 定向到空(&>/dev/null)或追加到文件中(&>>/tmp/run.log)
  • 避免不必要的程序及命令输出,如打包命令 tar -v 的显示过程的选项。
  • 打包压缩使用相对路径(切到目标目录的上一级打包目标,否则可能会带着一层目录)。示例如下:
cd /test1
tar czf ../b.tar.gz ./*
Bash

上一篇
下一篇