定时任务 crontab

crontab 是 Linux 的定时任务系统,可以按设定的时间自动执行命令或脚本。它是自动化运维的核心工具,广泛用于备份、日志清理、数据同步等场景。

基本概念

cron 是一个守护进程,每分钟检查一次是否有任务需要执行。crontab 是管理定时任务的命令,每个用户都可以有自己的 crontab 文件。

时间表达式

crontab 时间表达式由 5 个字段组成:

* * * * * 命令
│ │ │ │ │
│ │ │ │ └── 星期几 (0-7,0和7都是周日)
│ │ │ └──── 月份 (1-12)
│ │ └────── 日期 (1-31)
│ └──────── 小时 (0-23)
└────────── 分钟 (0-59)

特殊字符

字符含义
*任意值
,列举多个值
-范围
/步长

示例

# 每分钟执行
* * * * * /path/to/script.sh

# 每小时执行
0 * * * * /path/to/script.sh

# 每天凌晨 2 点执行
0 2 * * * /path/to/script.sh

# 每周一早上 8 点执行
0 8 * * 1 /path/to/script.sh

# 每月 1 日凌晨执行
0 0 1 * * /path/to/script.sh

# 每 5 分钟执行
*/5 * * * * /path/to/script.sh

# 每小时第 5、15、25 分钟执行
5,15,25 * * * * /path/to/script.sh

# 工作日早上 9 点执行
0 9 * * 1-5 /path/to/script.sh

# 每季度第一天执行
0 0 1 1,4,7,10 * /path/to/script.sh

管理定时任务

编辑定时任务

crontab -e

首次使用会提示选择编辑器。

查看定时任务

crontab -l

删除定时任务

crontab -r

删除前确认:

crontab -ri

编辑其他用户的定时任务

sudo crontab -u username -e
sudo crontab -u username -l

特殊字符串

一些系统支持特殊的时间字符串:

字符串含义
@yearly每年(0 0 1 1 *)
@monthly每月(0 0 1 * *)
@weekly每周(0 0 * * 0)
@daily每天(0 0 * * *)
@hourly每小时(0 * * * *)
@reboot重启后执行一次
@daily /path/to/backup.sh
@reboot /path/to/startup.sh

环境变量

cron 执行时的环境变量与登录 Shell 不同,PATH 可能不完整。建议在脚本中使用绝对路径:

# 在 crontab 中设置环境变量
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash

# 或在脚本中使用绝对路径
0 2 * * * /usr/bin/python3 /home/user/script.py

输出重定向

cron 任务默认会把输出发送到用户邮箱。建议重定向输出:

# 重定向到文件
0 2 * * * /path/to/script.sh >> /var/log/script.log 2>&1

# 丢弃输出
0 2 * * * /path/to/script.sh > /dev/null 2>&1

# 只记录错误
0 2 * * * /path/to/script.sh > /dev/null

常见问题

任务不执行

检查 cron 服务是否运行:

systemctl status cron
systemctl status crond

检查日志:

grep CRON /var/log/syslog
tail -f /var/log/cron

权限问题

确保脚本有执行权限:

chmod +x /path/to/script.sh

路径问题

使用绝对路径:

0 2 * * * cd /home/user/project && /home/user/project/script.sh

环境变量问题

在脚本开头加载环境:

#!/bin/bash
source ~/.bashrc

或在 crontab 中设置:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

实用示例

每日备份

0 2 * * * tar -czf /backup/data_$(date +\%Y\%m\%d).tar.gz /data

注意 % 在 crontab 中需要转义。

清理旧日志

0 3 * * * find /var/log -name "*.log" -mtime +7 -delete

定时同步

*/30 * * * * rsync -avz /data/ backup@remote:/backup/

定时检查服务

*/5 * * * * pgrep nginx > /dev/null || systemctl restart nginx

每周发送报告

0 8 * * 1 /home/user/send_report.sh | mail -s "Weekly Report" admin@example.com

小结

  • crontab 管理定时任务,5 个字段定义执行时间
  • crontab -e 编辑,crontab -l 查看,crontab -r 删除
  • 使用绝对路径,设置正确的环境变量
  • 重定向输出,避免邮件堆积
  • 检查日志排查问题