在GitHub上分享了一个解决方法sudo hwclock -s
来重新同步WSL中的时钟,但是每次从睡眠/休眠中恢复都需要执行此操作。
在GitHub上分享了一个解决方法sudo hwclock -s
来重新同步WSL中的时钟,但是每次从睡眠/休眠中恢复都需要执行此操作。
如果有人通过搜索找到这篇文章,并没有注意到问题中实际上已经列出了解决方案,你可以通过以下方式修复WSL时钟漂移。
sudo hwclock -s
如果您只需要偶尔这样做,这是一个不错的解决方案。如果您需要更频繁地这样做,请考虑 @piouson 的解决方案。
hwclock: Cannot access the Hardware Clock via any known method.
。 - Ryanhwclock
没有帮助。对我来说,sudo ntpdate ntp.ubuntu.com
起作用了。 - crockeea修复现在已经在WSL2 Linux内核的5.10.16.3
及更高版本中实现!请注意,您可能需要从Windows商店安装WSL2以获取最新的内核版本,参见这个与Microsoft的Craig的对话。
sudo hwclock -s
可以帮助您接近目标,但由于某种原因,它无法获得精确的时间-我经常发现它比实际时间快一分钟左右!
sudo ntpdate pool.ntp.org
应该可以为您提供正确的时间。
但这都是因为Linux内核中的一个错误,这个错误应该会在某个时候包含在Windows更新中...
在GitHub问题中引用了许多解决此问题的hack,但根据我的经验,它们并不总是有效...
wsl --status
显示“默认发行版:Ubuntu-22.04”、“默认版本:2”。 - user1507435只需重新启动WSL,对我来说它可以正常工作
wsl --shutdown
那么
wsl
在PowerShell中
sudo hwclock -s
会同步到 Windows,但其实不是。它实际上是将日期同步到您的硬件时钟。重新启动WSL(这正是此答案建议的方式)会将日期同步到Windows,因此您可以轻松地将Windows和WSL都更改为某个虚假日期。谢谢 :) - Float07更新:如drkvogel所提到的,时钟同步修复已在WSL2内核版本5.10.16.3中发布,但您应安装Windows Store版本的WSL:
# powershell install by id
winget install 9P9TQF7MRM4R
# powershell install by name
winget install 'Windows Subsystem for Linux'
撰写本文时,这个GitHub Issue仍然存在。
我选择的解决方法(在WSL2中使用单个发行版)是使用Windows任务计划程序,在Windows重新同步硬件时钟时运行hwclock
命令。
Windows:以管理员身份打开PowerShell
schtasks /create /tn WSLClockSync /tr "wsl.exe sudo hwclock -s" /sc onevent /ec system /mo "*[System[Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]"
Set-ScheduledTask WSLClockSync -Settings (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries)
sudo visudo
并将hwclock
添加到sudoers以跳过密码提示。# bottom of my file looks like this
...
...
#includedir /etc/sudoers.d
<username> ALL=(ALL) NOPASSWD:/usr/sbin/hwclock, /usr/bin/apt update, /usr/bin/apt upgrade
请参考图片中的步骤,获取Windows事件过滤器中的事件XPath。按照提供的方式使用,让任务计划程序自动显示预定的触发器。 这里有一个批处理脚本,可以自动完成这个过程,适用于每个已注册的发行版。Results
@echo off
rem this is a programmatic reminder of how to set up wsl clock sync
rem to prevent clock drift after sleep etc
rem see https://dev59.com/D1EG5IYBdhLWcg3wf_nV#65086857 and https://github.com/microsoft/WSL/issues/5324
set WSL_UTF8=1
setlocal EnableDelayedExpansion
for /F "tokens=* delims=" %%D in ('wsl --list --quiet') DO (
set hwclock_count=0
for /f "tokens=* delims=" %%C in ('wsl -d %%D bash -c "grep -c hwclock /etc/sudoers.d/hwclock 2>/dev/null"') DO set hwclock_count=%%C
if !hwclock_count! neq 1 (
echo Setting up sudo permissions for hwclock on distro %%D - will prompt for password...
wsl -d %%D sudo bash -c "echo -e '\x25adm ALL=(ALL) NOPASSWD:/usr/sbin/hwclock -s' > /etc/sudoers.d/hwclock"
) else echo hwclock permissions already set up with !hwclock_count! - not changing...
echo Testing resetting the clock - shouldn't prompt for password...
wsl -d %%D sudo /usr/sbin/hwclock -s
set syncname="WSLClockSync%%D"
echo Creating scheduled task %syncname%...
schtasks /create /f /tn "%syncname%" /tr "wsl.exe sudo hwclock -s" /sc onevent /ec system /mo "*[System[Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]"
echo Scheduling %syncname% to run even when on batteries...
powershell -command "& {Set-ScheduledTask %syncname% -Settings (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries)}"
echo Done!
)
/sbin/hwclock
。 - Don Alvarez5.10.102.1-microsoft-standard-WSL2
上的时钟不同步而找到了这篇文章。但是命令sudo hwclock -s
有效(Ubuntu 20.04)。 - M. Erikssonwsl.exe -u root hwclock -s
,就不需要使用 sudo
。 - undefined回复楼上的帖子:截至2022年5月,这个问题仍然存在。
该问题有两个组成部分。
首先,Windows时间同步需要合理。对于未加入域的计算机,默认情况下不合理。
更改w32time自动启动。在管理员cmd中(但不是PowerShell),输入sc triggerinfo w32time start/networkon stop/networkoff
。使用sc qtriggerinfo w32time
进行验证。通过此方式进入cmd,可以在管理员PowerShell中启动,然后只需键入cmd即可。
在regedit中进行几个更改。
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\Config
中,将MaxPollInterval
设置为十六进制c
,十进制12
。Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\Parameters\NtpServer
。如果以0x9
结尾,则完成。如果以0x1
结尾,则需要在Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\TimeProviders\NtpClient
中调整SpecialPollInterval
,使其读取3600
重新启动计算机,然后从PowerShell运行w32tm /query /status /verbose
以验证w32time服务是否已启动。如果未启动,请再次检查触发器。如果一切都失败了,请将其设置为自动延迟启动。
其次,WSL2需要保持同步。微软很可能会发布另一个内核修复程序。同时,可以使用定期计划任务将其带回同步状态:
schtasks /Create /TN WSL2TimeSync /TR "wsl -u root hwclock -s" /SC ONEVENT /EC System /MO "*[System[Provider[@Name='Microsoft-Windows-Kernel-Power'] and (EventID=107 or EventID=507) or Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]" /F
sudo hwclock -s
正如其他人之前所说的,sudo hwclock -s
可以同步时钟,但你需要在每次睡眠/休眠后执行此操作。解决方案是添加一个每小时运行的cron任务来同步时钟。
使用sudo打开crontab(由于该命令使用sudo,必须使用sudo打开):
sudo crontab -e
并在任务之后添加这段代码(这是cron的要求):
PATH=/sbin:/bin:/usr/bin
@hourly hwclock -s
因为root-cron没有PATH环境变量,所以您必须设置它,或使用绝对路径,例如/usr/sbin/hwclock
。
* * * * * date > /tmp/log.txt
pgrep cron
。sudo service cron start
启动cron。sudo apt install ntpdate
sudo ntpdate time.windows.com
sudo ntpdate time.windows.com
我大约6-9个月前开始遇到这个问题。 重启 wsl 总是有效的,但由于明显的原因,这并不理想。hwclock -s
通过 cron 定时作业定期运行几个月,但现在不再起作用了。@igor-alex 的方法对我有用,但需要一些不同的步骤:
/etc/wsl.conf(与上面相同)
[boot]
systemd=true
安装systemd-timesync(与上述相同)
sudo apt install systemd-timesyncd
对于 timesyncd 的建议编辑对我没有起作用,导致服务无法启动。相反,我采取了以下措施:
sudo systemctl edit systemd-timesyncd.service
[Unit]
ConditionVirtualization=
ConditionVirtualization=wsl
感谢https://unix.stackexchange.com/a/737366/547670提供的帮助。
并启动它(与上述相同)
sudo systemctl start systemd-timesyncd
HTH
ConditionVirtualization=
这一行注释掉。我使用的是Windows 11。 - undefinedwsl.exe -u root hwclock -s
,就不需要使用sudo
。 - undefined5.10.16.3
版本上仍然出现该问题(就像我的版本5.15.90.1
一样),您可以通过systemd服务来修复它。/etc/wsl.conf
中有以下内容:[boot]
systemd=true
然后安装 systemd-timesyncd
:
sudo apt install systemd-timesyncd
编辑 timesyncd 配置:
sudo systemctl edit systemd-timesyncd
使用(使其在虚拟化环境中运行):
[Unit]
ConditionVirtualization=
然后开始它:
sudo systemctl start systemd-timesyncd
感谢Github问题的解决方案。