先说结论:大多数主流 Linux 发行版(例如 Ubuntu、CentOS 等)所使用的 cron 守护进程(如 cronie 或 vixie-cron),默认会按照 系统设置的时区 来解释 crontab 文件中的时间计划。这个系统时区通常由 /etc/localtime 符号链接指向的时区文件决定。
一个实际场景是,在 Linux 服务器上使用 cron 配置 BorgBackup做增量备份 任务时,本意是设定在每周一凌晨2点执行。
0 2 * * 1 /data/backup/borg/backup.sh >> /var/log/borg-backup-cron.log 2>&1
结果却发现,时间到了早上10点多,备份进程仍在运行。最初怀疑是备份过程出现了 Bug,耗时异常。但仔细检查后才发现,问题的根源在于系统时间——这台服务器使用的是 UTC(格林威治)时间,而非预期的本地时间。明明开启了时间同步服务,为何时区设置会出问题呢?

具体来说:
- 如果你的系统时区设置为
Asia/Shanghai(UTC+8),那么在 crontab 中写入 0 2 * * 1,任务就会在每周一的北京时间凌晨2点准时触发。
- 需要注意的是,部分
cron 实现(例如 cronie)支持为单个 crontab 文件单独指定时区。你可以在 crontab 文件的开头通过 CRON_TZ 环境变量来设定,例如 CRON_TZ=UTC。
因此,解决上述备份时间错乱的问题,核心就在于将系统的时区正确设置为本地时间。对于使用 systemd 的现代 Linux 发行版,我们可以通过 timedatectl 命令轻松完成这一网络/系统配置。
设置步骤:
-
列出所有可用时区,并查找目标时区
我们可以通过管道和 grep 命令快速定位,例如查找上海时区:
timedatectl list-timezones | grep -i shanghai
-
设置系统时区
确认时区名称后,使用 set-timezone 参数进行设置:
timedatectl set-timezone Asia/Shanghai
-
验证时区设置
执行以下命令,检查当前的时间和时区信息是否已更新:
timedatectl
date

完成以上步骤后,系统的时区便已调整为北京时间(CST),cron 守护进程也将依据此本地时间来解析和执行你的定时任务,从而避免因时区误解导致的任务执行时间偏差。对于更复杂的定时任务管理和系统运维实践,你可以到 云栈社区 的相应板块与更多开发者交流探讨。
|