LoginSignup
3
3

WSL2における時刻のズレをPowerShellの力を借りて合わせるワンライナー

Last updated at Posted at 2024-01-26

論よりコード(結論)

前提条件

  • WSL2 内から Windows プロセスの起動を許可していること
  • PowerShell 7 以上であること
Ubuntu上のbashで
wsl.exe -u root date --set @$(pwsh.exe -Command 'Get-Date -UFormat %s')
#=> 設定日付が表示される (e.g. Fri Jan 26 12:25:47 JST 2024)

前提条件についての説明

Windows プロセスの起動を許可の件は、defaultが許可なので特に手を入れる必要はないはず。確認先は wsl.conf[interop] セクションの enabled キーの値が true です。
PowerShell の件は、Windows 標準添付は 1 や 5 だったりするので https://aka.ms/PSWindows から 7 をインストールしておきましょう。PowerShell 1 でもやる方法は後述。

どういうことなのか

2024年1月時点で標準入手できる Linux kernel では「WindowsとWSL2の時刻のずれを修正する」あるように、時刻がズレます。
同記事に書かれているように hwclock コマンドの参照先 /dev/rtc0 もズレてることがあるため、同記事ではファイルのタイムスタンプで Windows OS 側と同期する手法が紹介されていました。

仕組み

記事内では、時刻比較に PowerShell を使っているではありませんか。PowerShell 側から wsl.exe 経由で date コマンド実行しているわけです。逆も然りと考え、Linux(Ubuntu)側から PowerShell を呼び出し、その返却値を date --set に流し込んだというのが、この仕組みです。

  • PowerShell に Windows OS の時刻を基にした UNIX エポック秒を出力させる
  • date --set @エポック秒 の引数にする

date --set は root 権限が必要なため

  1. sudo で実行 (sudoerr に追加しておく準備が必要)
  2. wsl.exe -u root で実行 (事前準備無し)

どちらかで時刻設定ができます。

ちなみに PowerShell 1 だと Get-Date -UFormat %s の返却値はミリ秒込みになり、また(なぜか)+9時間されたあとの値になってしまい、そのまま date --set の引数に設定できなかったので、PowerShell 7 にしました。こちらは希望通りの操作になります。
どうしても PowerShell 1 でやりたい場合は

powershell.exe -Command '[int](Get-Date -UFormat %s)-32400'

という手もあります。

実際の使い勝手

pwsh.exe の呼び出しに300msくらいかかってるようなので、すこし詰まった感じはしますが、ntpdate するよりは速いでしょう。
あと、実行すると必ず日付表示がされるため wsl.exe -u root date ... > /dev/null とするのもよいでしょう。

私は .bashrc の先頭に、このワンライナーを入れておきました。これで Shell 起動毎に時刻を Windows OS 側と同期してくれるので、もはや心配なし!(だと思う)

あとがき

お昼にしよう。

EoT

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3