crontab命令用于安装、卸载或列出用于驱动cron守护进程的任务。每个用户都可以拥有自己的crontab文件,用于在指定的时间执行命令。
crontab [选项] [文件]
crontab [选项] -l [-u 用户]
crontab [选项] -r [-u 用户]
crontab [选项] -e [-u 用户]
/var/spool/cron/crontabs/目录中-u参数管理其他用户的任务crontab文件每行包含6个字段,前5个是时间字段,第6个是要执行的命令:
格式:
分钟 小时 日期 月份 星期 命令
字段说明:
| 字段 | 取值范围 | 特殊字符 |
|---|---|---|
| 分钟 | 0-59 | * , - / |
| 小时 | 0-23 | * , - / |
| 日期 | 1-31 | * , - / ? L W |
| 月份 | 1-12 或 JAN-DEC | * , - / |
| 星期 | 0-7 (0和7都表示周日) 或 SUN-SAT | * , - / ? L # |
| 命令 | 要执行的命令 |
| 字符 | 说明 | 示例 |
|---|---|---|
| * | 匹配所有值 | * 在分钟字段表示每分钟 |
| , | 指定多个值 | 1,15 表示第1和第15分钟 |
| - | 指定范围 | 1-5 表示1到5(包含1和5) |
| / | 指定间隔 | */5 表示每5个单位 |
| ? | 不指定值(仅在日期和星期字段) | 用于忽略其中一个字段 |
| L | 最后(Last) | L 在日期字段表示最后一天 |
| W | 工作日(Weekday) | 15W 表示离15号最近的工作日 |
| # | 第几个(仅在星期字段) | 6#3 表示每月的第三个星期五 |
cron支持一些特殊字符串,简化常见的时间调度:
| 字符串 | 含义 | 等价于 |
|---|---|---|
| @reboot | 系统启动时运行一次 | - |
| @yearly | 每年运行一次(1月1日 00:00) | 0 0 1 1 * |
| @annually | 同 @yearly | 0 0 1 1 * |
| @monthly | 每月运行一次(每月1日 00:00) | 0 0 1 * * |
| @weekly | 每周运行一次(周日 00:00) | 0 0 * * 0 |
| @daily | 每天运行一次(00:00) | 0 0 * * * |
| @midnight | 同 @daily | 0 0 * * * |
| @hourly | 每小时运行一次(每小时的0分) | 0 * * * * |
| 参数 | 说明 |
|---|---|
文件 |
包含cron任务的文件,用于安装新的crontab |
-u 用户 |
指定用户(只有root用户可以使用) |
-l |
列出当前用户的cron任务 |
-e |
编辑当前用户的cron任务 |
-r |
删除当前用户的cron任务(全部删除) |
-i |
与-r一起使用,交互式删除 |
-n 主机名 |
设置主机名(如果cron允许远程使用) |
-c |
获取指定用户的crontab路径 |
-V |
显示版本信息 |
-x 调试位 |
启用调试(需要编译时支持) |
编辑当前用户的crontab任务:
# 编辑当前用户的crontab
$ crontab -e
# 编辑指定用户的crontab(需要root权限)
$ sudo crontab -e -u username
# 编辑时使用默认编辑器(通常是vim或nano)
# 可以设置EDITOR环境变量更改编辑器
$ export EDITOR=nano
$ crontab -e
列出当前用户的所有cron任务:
# 列出当前用户的cron任务
$ crontab -l
# 列出指定用户的cron任务(需要root权限)
$ sudo crontab -l -u username
# 输出示例:
# 每天凌晨2点清理日志
0 2 * * * /usr/bin/find /var/log -name "*.log" -mtime +7 -delete
# 每小时检查磁盘空间
0 * * * * /usr/bin/df -h > /tmp/disk_space.txt
删除cron任务:
# 删除当前用户的所有cron任务
$ crontab -r
# 交互式删除(询问确认)
$ crontab -ri
# 删除指定用户的所有cron任务
$ sudo crontab -r -u username
# 注意:删除后无法恢复,建议先备份
$ crontab -l > ~/crontab_backup.txt
$ crontab -r
从现有文件安装crontab:
# 创建crontab文件
$ cat > ~/mycron.txt << 'EOF'
# 每分钟输出时间到文件
* * * * * date >> /tmp/time.log
# 每天凌晨3点备份
0 3 * * * /home/user/backup.sh
EOF
# 安装crontab
$ crontab ~/mycron.txt
# 验证安装
$ crontab -l
各种时间调度配置示例:
# 每分钟执行一次
* * * * * /path/to/command
# 每5分钟执行一次
*/5 * * * * /path/to/command
# 每小时的第5分钟执行
5 * * * * /path/to/command
# 每天凌晨2点执行
0 2 * * * /path/to/command
# 每天凌晨2点30分执行
30 2 * * * /path/to/command
# 每周一凌晨3点执行
0 3 * * 1 /path/to/command
# 每月1号凌晨4点执行
0 4 1 * * /path/to/command
# 每年1月1日早上6点执行
0 6 1 1 * /path/to/command
# 工作日的每小时执行
0 * * * 1-5 /path/to/command
# 周六周日的每小时执行
0 * * * 6,0 /path/to/command
# 每月的最后一天执行
0 0 28-31 * * [ $(date -d tomorrow +\%e) -eq 1 ] && /path/to/command
实际应用中的cron任务:
# 系统维护任务
# 每天清理临时文件
0 2 * * * find /tmp -type f -mtime +7 -delete
# 每周清理旧日志
0 3 * * 0 find /var/log -name "*.log" -mtime +30 -delete
# 每小时检查磁盘使用率
0 * * * * df -h | grep -E '(/|/home)$' > /var/log/disk_usage.log
# 每天备份数据库
0 1 * * * /usr/bin/mysqldump -u root -p密码 数据库名 > /backup/db_$(date +\%Y\%m\%d).sql
# 每分钟监控服务状态
* * * * * systemctl is-active --quiet nginx || systemctl restart nginx
# 每30分钟同步时间
*/30 * * * * /usr/sbin/ntpdate -s time.nist.gov
# 天气推送(使用curl获取)
0 8 * * * curl -s "https://wttr.in/Beijing?format=3" >> /tmp/weather.log
使用预定义的特殊字符串:
# 系统启动时运行
@reboot /path/to/startup_script.sh
# 每小时运行
@hourly /path/to/hourly_job.sh
# 每天运行
@daily /path/to/daily_backup.sh
# 每周运行
@weekly /path/to/weekly_cleanup.sh
# 每月运行
@monthly /path/to/monthly_report.sh
# 每年运行
@yearly /path/to/yearly_archive.sh
在crontab中设置环境变量和输出重定向:
# 在crontab文件顶部设置环境变量
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=user@example.com
# 任务示例
# 重定向标准输出到文件
0 * * * * /path/to/script.sh > /tmp/output.log 2>&1
# 重定向错误输出到文件
0 * * * * /path/to/script.sh 2> /tmp/error.log
# 输出到/dev/null(不保存输出)
0 * * * * /path/to/script.sh > /dev/null 2>&1
# 发送输出到指定邮箱
0 * * * * /path/to/script.sh | mail -s "Cron Job Output" user@example.com
调试和测试cron任务:
# 1. 检查cron服务状态
$ sudo systemctl status cron
$ sudo systemctl status crond # 某些系统
# 2. 查看cron日志
$ sudo tail -f /var/log/syslog | grep cron
$ sudo tail -f /var/log/cron # RHEL/CentOS
# 3. 手动运行命令测试
$ /path/to/script.sh
# 4. 测试环境变量
$ env -i /bin/bash -c "cd /home/user && /path/to/script.sh"
# 5. 在crontab中添加调试输出
* * * * * echo "Cron started at $(date)" >> /tmp/cron_debug.log
* * * * * /path/to/script.sh >> /tmp/cron_debug.log 2>&1
* * * * * echo "Cron ended at $(date)" >> /tmp/cron_debug.log
# 6. 检查命令是否存在
* * * * * which command_name > /tmp/which.log 2>&1
# 备份当前用户的crontab
crontab -l > ~/crontab_backup_$(date +\%Y\%m\%d).txt
# 备份所有用户的crontab
for user in $(cut -f1 -d: /etc/passwd); do
sudo crontab -u $user -l > /backup/crontab_${user}_$(date +\%Y\%m\%d).txt 2>/dev/null
done
A: 1) 检查cron服务是否运行;2) 查看cron日志;3) 检查脚本权限;4) 检查环境变量和路径;5) 手动执行脚本测试。
A: 使用@reboot特殊字符串,或者将cron服务添加到系统启动项。
A: 可以在脚本中判断时间,或者使用timeout命令限制执行时间。
A: 查看系统日志/var/log/syslog或/var/log/cron,或者在任务中自己记录日志。
A: 标准cron不支持秒级精度,最小单位是分钟。如果需要秒级精度,可以在脚本中使用sleep,或使用其他工具如systemd timer。
at - 一次性定时任务batch - 在系统负载允许时执行命令anacron - 处理非24小时运行系统的cron任务systemd.timer - systemd的定时器(现代替代方案)logrotate - 日志轮转工具(常用于cron)cron.d - 系统级cron目录(/etc/cron.d/)cron.hourly/daily/weekly/monthly - 预定义的cron目录