在 Linux 服务器上,定期执行备份、清理日志、发送报告等重复性工作,通常通过 cron 服务来完成。crontab 是管理这些定时任务的命令,每个用户可以拥有自己的 crontab 文件,系统也有全局的 /etc/crontab 和 /etc/cron.*/ 目录。
1. crontab 的基本操作
crontab -l # 列出当前用户的定时任务
crontab -e # 编辑当前用户的定时任务(会用默认编辑器打开)
crontab -r # 删除当前用户的所有定时任务(谨慎操作)
crontab -u 用户名 -l # root 用户查看指定用户的 crontab
编辑时的格式为:一行一个任务,由 时间表达式 和 要执行的命令 组成。
2. 时间表达式格式
一条 cron 任务的前五个字段依次表示:分 时 日 月 星期,后接命令。每个字段允许数字、(任意)、/N(每隔 N)、逗号分隔的具体值(如 1,15,30)以及范围(如 1-5)。
* * * * * /path/to/command
┬ ┬ ┬ ┬ ┬
│ │ │ │ └─ 星期 (0-7) (0或7均为周日)
│ │ │ └──── 月份 (1-12)
│ │ └────── 日期 (1-31)
│ └──────── 小时 (0-23)
└────────── 分钟 (0-59)
常见示例:
0 2 * * * /opt/backup.sh # 每天凌晨2点整执行备份脚本
*/5 * * * * /usr/bin/php monitor.php # 每5分钟执行一次PHP监控脚本
0 9-17 * * 1-5 /usr/bin/check # 周一至周五的9点到17点之间每小时整点执行
@reboot /usr/local/bin/startup.sh # 系统启动时执行一次
一些特殊字符串可以替代前五个字段:@yearly、@monthly、@weekly、@daily、@hourly、@reboot,但它们无法精确到分钟,更适合粗略周期。
3. 命令部分注意点
- 命令需要写绝对路径,因为 cron 执行时的
PATH环境变量通常只包含/usr/bin和/bin。不确定时可使用which command查看路径。 - 命令中的
%符号会被 cron 视为特殊字符,需要用\%转义,否则后面的内容会被当作标准输入。 - 若命令产生输出(stdout 或 stderr),cron 会尝试将输出以邮件形式发送给用户。为避免系统邮箱堆积无用信息,习惯上会重定向输出到文件或丢弃:
0 3 * * * /opt/script.sh > /var/log/script.log 2>&1
0 3 * * * /opt/script.sh > /dev/null 2>&1
4. 执行环境与常见陷阱
cron 的执行环境与交互式 Shell 大不相同:
PATH默认极简,可能找不到你平时能直接敲出的命令。- 不会读取
.bashrc、.profile等登录配置文件,因此自定义的环境变量、别名都不会生效。 - 工作目录通常是用户的家目录,但不要依赖于它,最好在脚本内
cd到绝对路径或使用绝对路径访问文件。 - 如果脚本依赖数据库连接、密钥等环境变量,需要在 crontab 文件开头显式声明(如
DB_HOST=localhost)或写在单独的环境文件中再用. /opt/env.sh && command引入。
调试建议:
在 crontab 中先写一个简单的任务测试是否能执行,比如每分钟输出日期到文件:
* * * * * echo "Cron ran at $(date)" >> /tmp/cron_test.log 2>&1
随后检查日志文件是否存在以及时间是否正确。逐步排除环境、权限和路径问题。
5. 系统级定时任务
除了用户自己的 crontab -e,发行版还提供了更精细的调度方式:
/etc/crontab:系统主 crontab 文件,格式比用户的多了“执行用户”字段(在时间表达式之后、命令之前)。/etc/cron.d/:放置自定义任务文件,格式同/etc/crontab,便于软件包管理各自的定时任务。/etc/cron.hourly/、/etc/cron.daily/、/etc/cron.weekly/、/etc/cron.monthly/:直接放入可执行脚本,由运行/etc/crontab中配置的run-parts按相应周期调用。通常用于系统维护任务(如 logrotate、mlocate 更新等)。
掌握 cron 定时任务,是服务器运维自动化的第一步。只要注意路径、环境变量和输出重定向这三个关键点,绝大多数定时执行需求都能稳定可靠地实现。