在日常的 Linux 运维工作中,自动化是提升效率和稳定性的关键。crontab 作为系统自带的定时任务管理器,无疑是实现自动化操作的核心工具之一。无论是数据库备份、日志清理,还是定期的系统健康检查与数据同步,只要是需要让服务器“到点自动执行”的任务,都离不开它。
本文将从 crontab 的基础概念讲起,涵盖高频实战案例,并分享一个“直接删除旧日志而无需编写独立脚本”的硬核命令技巧,旨在帮助你从理解到应用,快速掌握这一利器。
一、crontab 是什么?
简单来说,crontab 是 Linux 系统用于管理周期性计划任务的工具。它允许你在指定的时间(如每天凌晨、每周日、每分钟等),自动执行预设好的命令或脚本。这极大地解放了运维人员的双手,让许多重复性工作得以在无人值守的情况下自动完成,是构建稳定、高效运维/DevOps/SRE体系的基础组件。
二、5 个最常用的 crontab 命令
操作 crontab 主要通过几个简单的命令,以下是日常使用频率最高的五个:
# 查看当前用户的定时任务列表
crontab -l
# 编辑当前用户的定时任务(最常用)
crontab -e
# 删除当前用户的所有定时任务(慎用!)
crontab -r
# 查看 crond 定时任务服务的运行状态
systemctl status crond
# 重启 crond 服务(修改配置后未生效时可尝试)
systemctl restart crond
其中最核心的就是 crontab -e(编辑)和 crontab -l(查看),绝大部分操作都围绕它们展开。
三、理解 crontab 的时间格式
crontab 任务行的核心是时间表达式,它由五个时间字段和一个命令字段组成,格式如下:
* * * * * 要执行的命令或脚本
分 时 日 月 周
每个星号 * 代表一个时间字段,从左到右分别表示:
- 分钟 (0-59)
- 小时 (0-23)
- 日期 (1-31)
- 月份 (1-12)
- 星期 (0-7,其中0和7都代表周日)
除了 *,还支持一些特殊符号来定义复杂的时间点:
*:匹配该字段的所有有效值(如分钟字段的 * 表示每分钟)。
*/n:表示每隔 n 个单位时间执行一次(如 */5 在分钟字段表示每5分钟)。
a,b,c:指定多个离散的时间点(如 1,3,5)。
a-b:指定一个连续的时间范围(如 1-5)。
四、高频实战示例:执行脚本
以下是几种常见的、通过 crontab 调用 Shell 脚本的定时任务配置:
# 每分钟执行一次脚本
* * * * * /root/test.sh
# 每5分钟执行一次脚本(适合监控类任务)
*/5 * * * * /root/test.sh
# 每天凌晨2点整执行备份脚本
0 2 * * * /root/backup.sh
# 每天晚上8点30分执行任务
30 20 * * * /root/job.sh
# 每周日凌晨3点执行周备份
0 3 * * 0 /root/week_backup.sh
# 每月1号凌晨1点执行月度任务
0 1 1 * * /root/month_job.sh
# 工作日(周一至周五)早上7点执行任务
0 7 * * 1-5 /root/work.sh
五、高频实战示例:直接执行命令
对于简单的操作,你完全可以直接在 crontab 中编写命令,无需单独创建脚本文件。一个经典场景是定时清理旧日志。例如,我们需要每天自动删除 /data 目录下超过7天的日志文件(.log 后缀),可以这样做:
-
核心命令:使用 find 命令配合 -delete 参数,安全高效。
find /data -name "*.log" -mtime +7 -delete
-mtime +7:匹配7天以前(修改时间)的文件。
-delete:直接删除匹配到的文件。
-
安全第一:在将命令加入 crontab 前,强烈建议先手动运行不带 -delete 的命令预览将要删除的文件,确认无误。
find /data -name "*.log" -mtime +7
-
加入定时任务:将确认好的命令配置为每天凌晨2点执行。
0 2 * * * find /data -name "*.log" -mtime +7 -delete
六、特殊场景的进阶用法
1. 在每月最后一天执行任务
crontab 本身没有“最后一天”的直接语法,但可以通过日期判断巧实现。以下命令在每月28日至31日的晚上11点59分检查,如果次日是1号,则执行任务。
59 23 28-31 * * [ $(date +%d -d tomorrow) = 01 ] && /path/to/your_script.sh
2. 使用文件锁 (flock) 防止任务重复执行
如果一个脚本执行时间可能超过设定的间隔,需要防止前一个实例未结束就启动新实例,可以使用 flock 命令加锁。
0 2 * * * flock -n /tmp/backup.lock /path/to/backup.sh
-n:非阻塞模式,如果获取锁失败(即前一个任务仍在运行),则新任务直接退出。
3. 实现不规则间隔(如每90分钟执行一次)
crontab 最小粒度是分钟,且不支持直接设置90分钟间隔。但可以通过组合两条规则来实现:
# 规则A:在0,3,6,9,12,15,18,21点的0分执行
0 0-23/3 * * * /path/to/script.sh
# 规则B:在1,4,7,10,13,16,19,22点的30分执行
30 1-22/3 * * * /path/to/script.sh
这两条规则组合后,实际执行时间序列为:0:00 → 1:30 → 3:00 → 4:30 …,完美实现了90分钟的间隔。
七、日常配置注意事项(避坑指南)
-
脚本执行权限:确保你通过 crontab 调用的脚本具有可执行权限。
chmod +x /path/to/your_script.sh
-
使用绝对路径:crontab 执行环境中的 PATH 变量可能与你的交互式 Shell 不同。因此,在命令和脚本中,务必使用绝对路径。
- 错误示例:
sh backup.sh
- 正确示例:
/bin/sh /root/backup.sh
-
环境变量问题:crontab 运行环境非常“干净”,很多用户环境变量(如 JAVA_HOME, PYTHONPATH)可能不存在。稳妥的做法是在脚本内部显式设置或使用绝对路径调用解释器和命令。
八、定时任务不执行?如何排查
当你发现配置好的任务没有按时运行时,可以按照以下步骤排查:
- 确认任务是否存在:执行
crontab -l,检查你的任务条目是否被正确保存。
- 确认服务是否运行:执行
systemctl status crond,确保 crond 服务处于 active (running) 状态。
- 查看系统日志:crontab 的执行记录会记录在系统日志中(通常是
/var/log/cron 或通过 journalctl 查看)。这是最直接的排错手段。
tail -f /var/log/cron
- 注意时间表达式的理解误区:一个常见的错误是关于“每隔 N 小时”的写法。
0 */2 * * *:正确。表示每2小时的0分执行(即 0:00, 2:00, 4:00…)。
* */2 * * *:错误。这表示在每2小时内的每一分钟都执行,这通常不是你想要的效果。
总结
crontab 的语法虽然简单,但其在 Linux 自动化运维中的作用不可小觑。很多初级错误都源于对路径、环境以及时间表达式细节的忽视。希望这篇从基础到进阶的指南能成为你手边的实用参考,在需要配置定时任务时,随时查阅、复制、修改,真正提升你的工作效率和系统可靠性。记住,在将任何删除或关键操作加入定时任务前,手动测试永远是保证安全的第一步。