linux crontab命令

crontab命令用于安装、卸载或列出用于驱动cron守护进程的任务。每个用户都可以拥有自己的crontab文件,用于在指定的时间执行命令。

语法格式

crontab [选项] [文件]
crontab [选项] -l [-u 用户]
crontab [选项] -r [-u 用户]
crontab [选项] -e [-u 用户]

命令功能

  • 创建、编辑、查看和删除cron定时任务
  • 管理用户的定时任务调度
  • 支持复杂的时间调度规则
  • 自动执行备份、监控、清理等任务
  • 每个用户独立的任务列表

📝 重要说明

  • crontab文件存储在/var/spool/cron/crontabs/目录中
  • 只有root用户可以使用-u参数管理其他用户的任务
  • cron任务的执行结果会通过邮件发送给用户(默认发送到本地邮箱)
  • cron任务运行的环境变量与登录shell不同
  • 任务中的命令需要使用绝对路径

cron时间格式

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 调试位 启用调试(需要编译时支持)

常用示例

示例1:编辑crontab文件

编辑当前用户的crontab任务:

# 编辑当前用户的crontab
$ crontab -e

# 编辑指定用户的crontab(需要root权限)
$ sudo crontab -e -u username

# 编辑时使用默认编辑器(通常是vim或nano)
# 可以设置EDITOR环境变量更改编辑器
$ export EDITOR=nano
$ crontab -e

示例2:查看crontab任务

列出当前用户的所有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

示例3:删除crontab任务

删除cron任务:

# 删除当前用户的所有cron任务
$ crontab -r

# 交互式删除(询问确认)
$ crontab -ri

# 删除指定用户的所有cron任务
$ sudo crontab -r -u username

# 注意:删除后无法恢复,建议先备份
$ crontab -l > ~/crontab_backup.txt
$ crontab -r

示例4:从文件安装crontab

从现有文件安装crontab:

# 创建crontab文件
$ cat > ~/mycron.txt << 'EOF'
# 每分钟输出时间到文件
* * * * * date >> /tmp/time.log
# 每天凌晨3点备份
0 3 * * * /home/user/backup.sh
EOF

# 安装crontab
$ crontab ~/mycron.txt

# 验证安装
$ crontab -l

示例5:常见时间调度示例

各种时间调度配置示例:

# 每分钟执行一次
* * * * * /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

示例6:实用cron任务示例

实际应用中的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

示例7:使用特殊字符串

使用预定义的特殊字符串:

# 系统启动时运行
@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

示例8:设置环境变量和重定向输出

在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

示例9:调试cron任务

调试和测试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

⚠️ 注意事项

  1. 环境变量:cron执行环境与用户登录环境不同,建议在脚本中设置完整路径
  2. 权限问题:确保脚本有执行权限,且cron用户有权访问所需文件
  3. 输出处理:cron任务输出会通过邮件发送,建议重定向到文件或/dev/null
  4. 时间设置:注意服务器的时区设置,cron使用系统时区
  5. 资源限制:避免任务过于频繁或耗时过长,影响系统性能
  6. 依赖关系:确保任务所需的服务和资源在任务执行时可用

💡 实用技巧

  1. 备份crontab:定期备份crontab配置
    # 备份当前用户的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
  2. 使用绝对路径:在cron任务中总是使用命令的绝对路径
  3. 日志记录:重要的cron任务应该记录执行日志
  4. 测试脚本:先手动测试脚本,再添加到crontab
  5. 锁定文件:长时间运行的任务使用锁文件防止重复执行

常见问题

Q: cron任务没有执行怎么办?

A: 1) 检查cron服务是否运行;2) 查看cron日志;3) 检查脚本权限;4) 检查环境变量和路径;5) 手动执行脚本测试。

Q: 如何让cron任务在重启后自动运行?

A: 使用@reboot特殊字符串,或者将cron服务添加到系统启动项。

Q: cron任务可以限制执行时间吗?

A: 可以在脚本中判断时间,或者使用timeout命令限制执行时间。

Q: 如何查看cron任务的执行历史?

A: 查看系统日志/var/log/syslog/var/log/cron,或者在任务中自己记录日志。

Q: 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目录