Linux Crontab定时任务完全指南:语法详解、常用场景与执行异常排查
Crontab是Linux服务器自动化的基石工具,从每天凌晨备份数据库、定时清理日志,到每小时同步文件、每分钟检查服务状态,几乎所有周期性任务都依赖cron来完成。本文从语法到实战,给出完整指南。
一、Cron表达式语法
# crontab格式:
# 分钟 小时 日期 月份 星期 命令
# * * * * * /path/to/command
# 0~59 0~23 1~31 1~12 0~7(0和7均为周日)
# 特殊符号:
# * 代表所有可能的值(每分钟/每小时/每天)
# , 列举多个值(1,3,5 = 1日、3日、5日)
# - 范围(1-5 = 周一到周五)
# / 间隔频率(*/5 = 每5分钟)常用时间表达式速查
| Cron表达式 | 执行时间 |
|---|---|
0 3 * * * | 每天凌晨3:00 |
30 2 * * 0 | 每周日凌晨2:30 |
0 0 1 * * | 每月1日零点 |
*/5 * * * * | 每5分钟 |
0 */2 * * * | 每2小时整点 |
0 9-18 * * 1-5 | 工作日9:00~18:00每小时 |
0 3 * * 1,3,5 | 每周一、三、五凌晨3点 |
@reboot | 系统重启后执行一次 |
@daily | 等同于 0 0 * * * |
@weekly | 等同于 0 0 * * 0 |
二、Crontab基础操作
<code"># 编辑当前用户的crontab crontab -e # 查看当前用户的crontab crontab -l # 删除当前用户的crontab crontab -r # 以特定用户身份编辑(需要root权限) crontab -u www-data -e # 编辑系统级crontab(格式多一列"用户") nano /etc/crontab
三、常用场景配置实战
场景1:每日自动备份数据库
<code"># 每天凌晨2点备份MySQL数据库
0 2 * * * /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1
# mysql-backup.sh内容
#!/bin/bash
DATE=$(date +%Y%m%d)
mysqldump -u root -p'数据库密码' --all-databases | gzip > /backup/db_${DATE}.sql.gz
find /backup -name "db_*.sql.gz" -mtime +30 -delete
echo "$(date): 数据库备份完成"场景2:定时清理日志文件
<code"># 每周日凌晨3点清理30天前的日志 0 3 * * 0 find /var/log/nginx -name "*.gz" -mtime +30 -delete # 每天凌晨4点清理临时文件 0 4 * * * find /tmp -type f -mtime +7 -delete # 每天清理Docker无用镜像和容器 0 5 * * * docker system prune -f >> /var/log/docker-prune.log 2>&1
场景3:Let's Encrypt证书续签
<code"># 每天凌晨3点尝试续签(证书只在剩余30天内才真正续签) 0 3 * * * certbot renew --quiet && systemctl reload nginx
场景4:定时同步文件到备份服务器
<code"># 每小时同步网站文件到备份服务器 0 * * * * rsync -az --delete /var/www/html/ backup-server:/backup/www/ >> /var/log/rsync.log 2>&1
场景5:服务健康检查与自动重启
<code"># /usr/local/bin/health-check.sh
#!/bin/bash
# 检查Nginx是否运行,否则重启
if ! systemctl is-active --quiet nginx; then
systemctl start nginx
echo "$(date): Nginx已重启" >> /var/log/health-check.log
fi
# 检查PHP-FPM是否运行
if ! systemctl is-active --quiet php8.1-fpm; then
systemctl start php8.1-fpm
echo "$(date): PHP-FPM已重启" >> /var/log/health-check.log
fi
# 检查网站可访问性(HTTP 200)
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/)
if [ "$HTTP_CODE" != "200" ]; then
echo "$(date): 网站异常,状态码: $HTTP_CODE" >> /var/log/health-check.log
# 发送告警通知...
fi<code"># 每5分钟执行一次健康检查 */5 * * * * /usr/local/bin/health-check.sh
场景6:WordPresswp-cron替换(提升性能)
<code"># 禁用WordPress内置Cron(每次访问触发,性能差)
# wp-config.php中添加:
# define('DISABLE_WP_CRON', true);
# 改为系统cron定时触发(每15分钟)
*/15 * * * * cd /var/www/html && php wp-cron.php > /dev/null 2>&1
# 或使用WP-CLI
*/15 * * * * /usr/local/bin/wp cron event run --due-now --path=/var/www/html --allow-root四、Crontab最佳实践
1. 使用绝对路径
<code"># 错误:Cron环境PATH不完整,可能找不到命令 */5 * * * * python3 /scripts/check.py # 正确:使用绝对路径 */5 * * * * /usr/bin/python3 /scripts/check.py # 或在脚本顶部设置PATH #!/bin/bash export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
2. 重定向输出避免邮件堆积
<code"># 默认情况下,Cron会把命令输出发送到root邮件(/var/mail/root会积累大量邮件) # 将输出重定向到日志文件 0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1 # 或完全丢弃输出(不推荐,无法排查问题) 0 3 * * * /usr/local/bin/backup.sh > /dev/null 2>&1
3. 添加任务说明注释
<code"># 每天凌晨2点:备份MySQL数据库(保留30天) 0 2 * * * /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1 # 每周日3点:同步文件到异地备份服务器 0 3 * * 0 /usr/local/bin/offsite-backup.sh >> /var/log/offsite.log 2>&1
五、Crontab任务不执行排查
排查步骤清单
<code"># 1. 确认cron服务正在运行 systemctl status cron # 或 crond(CentOS) # 2. 查看cron执行日志 grep CRON /var/log/syslog | tail -50 # 或 journalctl -u cron | tail -50 # 3. 确认脚本有执行权限 chmod +x /usr/local/bin/your-script.sh # 4. 手动测试脚本是否能正常执行 sudo -u root /usr/local/bin/your-script.sh # 5. 检查脚本中的命令是否使用绝对路径 which python3 # 查找绝对路径 which mysqldump # 6. 验证cron表达式是否正确 # 使用在线工具:https://crontab.guru/
六、Systemd Timer:现代化的Cron替代
Systemd Timer是比crontab更强大的定时任务方案,支持更精确的时间控制、依赖管理和日志集成:
<code"># /etc/systemd/system/backup.service [Unit] Description=每日数据库备份 [Service] Type=oneshot ExecStart=/usr/local/bin/mysql-backup.sh User=root
<code"># /etc/systemd/system/backup.timer [Unit] Description=每日凌晨2点触发备份 [Timer] OnCalendar=*-*-* 02:00:00 Persistent=true # 若错过执行时间(如服务器关机),重启后立即补执行 [Install] WantedBy=timers.target
<code"># 启用并启动Timer systemctl daemon-reload systemctl enable backup.timer systemctl start backup.timer # 查看所有Timer状态 systemctl list-timers
七、总结
Crontab是服务器自动化运维不可缺少的工具,掌握语法和最佳实践后,可以让大量重复性任务完全自动化。建议关键任务(备份、续签、健康检查)都通过Crontab定时执行,并配合日志记录方便排查问题。IDC.Net的香港VPS系统时间默认UTC+8,与中国大陆时区一致,配置定时任务时无需额外调整时区偏移。
版权声明:
作者:后浪云
链接:https://idc.net/help/442782/
文章版权归作者所有,未经允许请勿转载。
THE END
