![Ubuntu 22.04 Jammy - cron 似乎忽略了时区](https://linux22.com/image/787344/Ubuntu%2022.04%20Jammy%20-%20cron%20%E4%BC%BC%E4%B9%8E%E5%BF%BD%E7%95%A5%E4%BA%86%E6%97%B6%E5%8C%BA.png)
我有一个配置为使用时区的服务器Pacific/Auckland
,但是 cron 正在运行UTC
。
在以前的操作系统版本中,这足以让所有内容使用指定的时区运行(包括 cron):
sudo ln -sf /usr/share/zoneinfo/$TIMEZONE /etc/localtime
echo "$TIMEZONE" | sudo tee /etc/timezone
sudo dpkg-reconfigure --frontend noninteractive tzdata
sudo timedatectl set-timezone $TIMEZONE
上面的方法似乎在除 cron 之外的任何地方都有效 -date
和timedatectl
都返回预期的结果,但 cron 仍然以 UTC 运行,即
$ date
Wed Jul 5 12:50:01 NZST 2023
$ timedatectl
Local time: Wed 2023-07-05 12:50:01 NZST
Universal time: Wed 2023-07-05 00:50:01 UTC
RTC time: Wed 2023-07-05 00:50:00
Time zone: Pacific/Auckland (NZST, +1200)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
在 crontab 中添加类似这样的内容57 0 * * * date >> /tmp/cron-test.log
会导致输出Wed Jul 5 12:57:01 NZST 2023
写入日志文件。我的理解是 cron 应该在本地时间运行,但这并不是我观察到的。
我读过几个 StackOverflow 帖子,并尝试了以下方法,但无济于事:
- 设置
TZ
和CRON_TZ
/etc/crontab
- 设置
TZ
和CRON_TZ
crontab -e
- 设置
TZ
和CRON_TZ
/etc/environment
- 设置
TZ
和CRON_TZ
系统/etc/systemd/system/cron.service.d/override.conf
日志说它忽略了这一点 - 设置
TZ
和CRON_TZ
在Service/Environment
/etc/systemd/system/cron.service.d/override.conf
每次尝试后我都会跑sudo systemctl daemon-reload && sudo service cron restart
。
我的观察是,设置TZ
在任何情况下的唯一效果是更改 crontab 中运行的命令的时区,而不是 cron 本身。设置CRON_TZ
对任何事情都没有影响。
我也尝试过这个,env -i $(cat /proc/$(</var/run/crond.pid)/environ|xargs -0 echo) date +%Z
试图查看 cron 在哪个时区运行,它返回了NZST
它应该运行的时区,但不幸的是,情况似乎并非如此......
我发现这个帖子中有人看到了几乎相同的行为:https://ubuntuforums.org/showthread.php?t=2477727- 对他来说,更新软件包并重新启动似乎已经解决了这个问题,但这对我来说似乎不起作用。
任何智慧都将受到赞赏。
更新 1
这个帖子cron 采用 UTC 时间而不是本地时间有一个似乎适用于我的情况的答案:
如果你没有将硬件时间设置为与系统时间匹配,那么 cron 将根据硬件时间运行
运行sudo timedatectl set-local-rtc 1
似乎让 cron 在正确的时间运行片刻,但输出下面的内容,然后在一段时间后重置为 UTC。
timedatectl status
Local time: Wed 2023-07-05 14:13:01 NZST
Universal time: Wed 2023-07-05 02:13:01 UTC
RTC time: Wed 2023-07-05 14:13:01
Time zone: Pacific/Auckland (NZST, +1200)
System clock synchronized: yes
NTP service: active
RTC in local TZ: yes
Warning: The system is configured to read the RTC time in the local time zone.
This mode cannot be fully supported. It will create various problems
with time zone changes and daylight saving time adjustments. The RTC
time is never updated, it relies on external facilities to maintain it.
If at all possible, use RTC in UTC by calling
'timedatectl set-local-rtc 0'.
因此,cron 似乎是在硬件时间上运行的。不幸的是,不建议将硬件时钟设置为本地时间,而且无论如何都会被撤消。遗憾的是,这不是解决方案,但确实开辟了另一条调查途径。
更新2
对硬件时钟的调查让我发现了以下几点:
- 你可以通过几种不同的方式将其设置为使用本地时间 - sudo
hwclock --systohc --localtime
和timedatectl set-local-rtc 1
- 我发现这一页有人在那里讨论传统的方法和
/etc/adjtime
文件。
事实证明,timedatectl
和都以不同的方式hwclock
更新文件和。使用任何一种机制将其设置为本地时间都会产生抱怨。然而,在运行之前似乎保留了一些设置,允许 cron 在正确的时间运行并防止抱怨。/etc/adjtime
timedatectl status
hwclock --systohc --localtime
timedatectl set-local-rtc 0
timedatectl status
此时 cron 运行正常,但我不确定 NTP 更新后设置是否会保留。我将尝试重建一些服务器,并回答问题是否能解决问题。
答案1
按照这个答案经过沃伦- 问题是 cron 使用的是硬件时钟而不是系统时钟。
我发现执行以下操作可以解决此问题:
# use local time for hardware time and set drift factor
hwclock --systohc --localtime
# use UTC time for hardware time
timedatectl set-local-rtc 0
这会使硬件时钟使用本地时间,并创建一个配置文件,然后/etc/adjtime
将硬件时钟恢复为 UTC,但保留配置文件。请注意,timedatectl set-local-rtc 1
不会设置配置参数这是为了工作所必需的,所以hwclock
似乎是必需的。
上述解决方案创建的配置/etc/adjtime
似乎使 cron 在正确的时区运行,而不会破坏 NTP 更新之类的操作。
这可能不是最好的解决方案,但它确实解决了问题。