什么是 cron?
cron 是内置于每个 Linux 发行版中的基于时间的任务调度器。它会在固定的时间、日期或间隔自动运行命令和脚本——非常适合备份、日志轮转、证书续期、数据库清理以及触发应用程序调度器等场景。在 Ubuntu 上,该调度器作为一个名为 cron.service 的后台服务运行,而你要运行的内容则定义在称为 crontab 的文件中。
本指南涵盖 Ubuntu 22.04/24.04 LTS 上的用户级和系统级 cron 任务、精确的语法、如何处理环境变量与日志,以及如何让计划任务在托管 VPS 或云服务器上稳定可靠地运行。
检查 cron 是否已安装并正在运行
在 Ubuntu 上,cron 守护进程由 cron 软件包提供,通常已经预装。验证一下:
systemctl status cron
你应当看到 Active: active (running)。如果该软件包缺失,请安装并启用它:
sudo apt update && sudo apt install -y cron
sudo systemctl enable --now cron
理解 crontab 语法
每个 cron 任务都是一行,包含五个时间与日期字段,后面跟着要运行的命令:
# ┌───────────── minute (0–59)
# │ ┌───────────── hour (0–23)
# │ │ ┌───────────── day of month (1–31)
# │ │ │ ┌───────────── month (1–12)
# │ │ │ │ ┌───────────── day of week (0–7, where 0 and 7 are Sunday)
# │ │ │ │ │
# * * * * * command to execute
每个字段可以接受:
| 运算符 | 含义 | 示例 |
|---|---|---|
* |
每一个值 | * * * * * = 每分钟 |
, |
列表 | 0,30 * * * * = 在第 :00 和 :30 分 |
- |
范围 | 0 9-17 * * * = 上午 9 点至下午 5 点每小时 |
/ |
步长 | */15 * * * * = 每 15 分钟 |
几个实际示例:
0 2 * * * # every day at 02:00
*/5 * * * * # every 5 minutes
30 3 * * 1 # 03:30 every Monday
0 0 1 * * # midnight on the 1st of every month
0 8 * * 1-5 # 08:00 Monday–Friday
你也可以使用这些简写字符串来替代五个字段:@reboot、@hourly、@daily、@weekly、@monthly 和 @yearly。例如,@reboot 会在服务器每次启动时运行一次任务。
创建用户级 cron 任务
大多数应用程序任务都应当以普通用户身份运行,而不是 root。使用以下命令编辑你的用户 crontab:
crontab -e
第一次执行时,系统会要求你选择一个编辑器(nano 是最简单的)。添加一个任务——例如,每天凌晨 1:30 运行一个备份脚本并记录其输出:
30 1 * * * /home/deploy/scripts/backup.sh >> /home/deploy/logs/backup.log 2>&1
保存并退出。cron 会立即安装新的计划——无需重启。使用 crontab -l 列出你的任务,使用 crontab -r 删除全部任务(请谨慎使用)。
>> file 2>&1 这部分会将标准输出和错误一并追加到日志文件中。这一点很重要:默认情况下 cron 会将输出以邮件方式发送给本地用户,而你通常永远看不到这些邮件,因此显式记录日志正是调试故障的方式。
系统级任务与 run-parts 目录
root 级和软件包附带的任务位于 /etc/crontab 和 /etc/cron.d/ 中。这些文件在时间字段和命令之间多出一个字段——用户名:
# m h dom mon dow user command
0 4 * * * root /usr/local/bin/cleanup.sh
对于常见情况,你甚至无需编写计划。Ubuntu 会按固定节奏运行你放入这些目录中的任何内容:
/etc/cron.hourly/
/etc/cron.daily/
/etc/cron.weekly/
/etc/cron.monthly/
将一个可执行脚本(不带文件扩展名,并执行 chmod +x)放入 /etc/cron.daily/,它就会每天运行一次。这是发布维护脚本最简洁的方式。
环境变量与 PATH 的坑
任务"在我的 shell 里能用,但在 cron 里却不行"的最常见原因就是环境。cron 在一个极简的 PATH(通常是 /usr/bin:/bin)下运行,并且不会加载你的 .bashrc 或 profile。两种修复方法:
- 始终对二进制文件和文件使用绝对路径(用
/usr/bin/php,而不是php)。 - 在 crontab 顶部设置变量:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=ops@example.com
SHELL=/bin/bash
*/10 * * * * cd /var/www/app && /usr/bin/php artisan schedule:run >> /var/log/app-cron.log 2>&1
注意,MAILTO="" 会禁用所有邮件;将其设置为某个地址,则在配置了邮件程序的情况下会把任务输出发送到那里。
时区
cron 使用的是服务器的系统时区,而非你的本地时区——当你的团队在利雅得,而 VPS 默认使用 UTC 时,这一点很容易被忽视。检查并设置时区:
timedatectl # shows current time zone
sudo timedatectl set-timezone Asia/Riyadh
更改时区后,重启 cron 以便正在运行的任务采用新时区:sudo systemctl restart cron。将你的服务器托管在沙特境内意味着它天然与利雅得时间以及 PDPL 数据驻留要求保持一致。
验证与调试任务
在 Ubuntu 上,cron 活动会记录到系统日志(journal)和 /var/log/syslog 中(默认没有单独的 /var/log/cron)。实时查看执行情况:
grep CRON /var/log/syslog | tail
journalctl -u cron --since "1 hour ago"
如果某个任务没有触发,请按以下顺序检查:cron 服务正在运行、该行恰好有五个时间字段(或一个 @ 字符串)、脚本是可执行的,以及你的日志文件中显示了命令输出。要验证一个脚本在 cron 精简后的环境中能否正常工作,可以用 env -i /bin/bash -c '/path/to/script.sh' 来测试它。
限制谁可以使用 cron
要控制哪些用户可以安装 crontab,可以创建 /etc/cron.allow(白名单)或 /etc/cron.deny(黑名单)。如果 /etc/cron.allow 存在,那么只有列出的用户才能使用 crontab——这是在共享服务器上一个明智的加固步骤。
在 Skyline Cloud 上稳定可靠地运行
cron 任务的可靠程度,取决于它所运行的服务器。在 Skyline Cloud 的 VPS 或云服务器上,你的计划备份、报表生成和续期任务运行在始终在线的基础设施之上,该基础设施托管于沙特数据中心,提供本地阿拉伯语支持,并符合 PDPL/NCA 的数据驻留要求。再搭配 Skyline 企业邮箱托管服务,让关于失败任务的 MAILTO 告警能够真正送达你的团队。
准备好在沙特境内的基础设施上自动化你的工作负载了吗?创建你的 Skyline Cloud 账户,几分钟内即可部署一台 VPS。
Comments
0 total · 0 threads