VPS上很多事不该手动做——每天备份数据库、每周更新系统、每月清理旧日志。crontab是Linux内置的定时任务调度器,几行配置就能让这些重复劳动自动跑。
crontab基础语法
编辑当前用户的定时任务:crontab -e。时间格式:分 时 日 月 星期 命令。
# 每行一个任务,格式:
# * * * * * /path/to/command
# │ │ │ │ │
# │ │ │ │ └─ 星期(0-7,0和7=周日)
# │ │ │ └─── 月份(1-12)
# │ │ └───── 日期(1-31)
# │ └─────── 小时(0-23)
# └───────── 分钟(0-59)常用示例:
# 每天凌晨3点
0 3 * * * /script.sh
# 每30分钟
*/30 * * * * /script.sh
# 每周日凌晨2点
0 2 * * 0 /script.sh
# 每月1号凌晨4点
0 4 1 * * /script.sh
# 工作日每小时(周一到周五)
0 * * * 1-5 /script.sh常用自动化脚本模板
数据库定时备份:
#!/bin/bash
# /root/scripts/backup_db.sh
BACKUP_DIR="/backup/db"
RETENTION_DAYS=7
mkdir -p "$BACKUP_DIR"
mysqldump -u root --all-databases | gzip > "$BACKUP_DIR/db_$(date +%Y%m%d).sql.gz"
# 删除7天前的旧备份
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
# 可选:传到对象存储
coscmd upload "$BACKUP_DIR/db_$(date +%Y%m%d).sql.gz" /backup/chmod +x /root/scripts/backup_db.sh
# 加到crontab:每天凌晨2点备份
0 2 * * * /root/scripts/backup_db.sh >> /var/log/backup.log 2>&1系统自动更新:
#!/bin/bash
# /root/scripts/auto_update.sh
apt update && apt upgrade -y && apt autoremove -y
# 检查是否需要重启(内核更新了)
if [ -f /var/run/reboot-required ]; then
echo "$(date): System reboot required" >> /var/log/update.log
# 如果要在凌晨自动重启,取消下面注释:
# reboot
fi0 4 * * 0 /root/scripts/auto_update.sh >> /var/log/update.log 2>&1
# 每周日凌晨4点更新日志清理:
# 清理nginx日志,保留30天
0 2 * * * find /var/log/nginx -name "*.log" -mtime +30 -delete
# 清理Docker日志(Docker容器日志会无限增长)
0 3 * * 0 echo "" > $(docker inspect --format='{{.LogPath}}' 容器名)雨云入门VPS月付几块钱就能跑这些自动化任务——crontab不额外吃资源。优惠码 admin01 首月五折。
crontab排错和调试
定时任务运行了但没效果的最常见原因:
- PATH环境变量:cron运行的环境PATH只有/usr/bin:/bin。脚本里不要写mysql要写/usr/bin/mysql的完整路径。或者脚本开头加PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin。
- 日志输出:脚本输出不会显示在终端,要重定向到文件——结尾加 >> /var/log/xxx.log 2>&1。2>&1把报错也写进去。
- 权限问题:cron以当前用户身份运行。root的crontab(sudo crontab -e)有root权限,普通用户crontab只有普通权限——备份/etc下的文件需要root。
- 百分比符号:crontab里%是特殊字符(表示换行),要转义写成%。
测试定时任务:设一个”每分钟执行”的测试——* * * * * echo “test at $(date)” >> /tmp/cron_test.log——过一分钟看/tmp/cron_test.log有没有内容。
vs systemd Timer
现代Linux推荐用systemd Timer替代crontab做定时任务——有更好的日志管理、依赖控制和随机延迟功能。但配置更复杂(需要写两个文件:.timer和.service)。简单定时任务crontab一行搞定,复杂任务推荐systemd Timer。
常见问题
crontab任务没执行怎么排查?
三个地方看:syslog里找CRON关键字(grep CRON /var/log/syslog);确认cron服务在跑(systemctl status cron);检查脚本是否有执行权限(chmod +x)。90%的问题出在PATH或权限。
定时任务可以互斥吗?上一次没跑完下一次别跑?
crontab不内置互斥。用flock加文件锁解决:flock -n /tmp/script.lock /script.sh——-n表示如果锁已被占用就直接退出。防止一个任务没跑完下一个又启动了导致N个实例同时跑。
crontab和其他定时方案选哪个?
简单的备份清理用crontab;复杂工作流(先备份→压缩→上传→通知)用脚本+crontab调用;需要精确调度和依赖管理的用systemd Timer;需要可视化管理多台VPS的用Jenkins/Rundeck。






