WSL上のcronで時刻を定期的に修正する

4996 ワード

はじめに

WSLはなぜか時計(システムクロック)がよく狂います。修正するためには、

sudo hwclock -s

を実行する必要があります。-s--hctosysの短縮オプションで、システムクロックをハードウェアクロックに合わせるものです。で、これを毎回気が付いた時にやるのは面倒なので、cronで定期実行したいですね。でも、WSLはデフォルトでcronが動いていません。これをなんとかしましょう、という話です。

sudo hwclockをパスワードなしに

まず、hwclockによるハードウェアクロックへのアクセスにはroot権限が必要なので、sudo hwclockする必要があります。すると、パスワードが要求されてしまいます。これではcronに載せられないので、パスワードなしに実行できるようにしましょう。事前にhwclockのパスを調べておきます。

$ which hwclock
/sbin/hwclock

場合によって/usr/sbin/だったりするようです(18から20に上げたりすると場所が違う?)。

次に/etc/sudoersを編集します。編集に失敗するとsudoコマンドが使えなくなって面倒なので、visudoを使って修正すると良いでしょう。ファイルフォーマットが不正だと警告してくれるようになります。ただ、Ubuntuのデフォルトエディタはnanoなので、Vimを使いたい人は、あらかじめsudo apt purge nanoとかしておくと幸せかもしれません(crontab -eなんかも同様)。

sudo visudo

そして、/etc/sudoersの最後あたりに以下の行を追加します。

username ALL=NOPASSWD: /sbin/hwclock

usernameは自分のアカウント名を入れてください。

sudo hwclock

を実行し、パスワードを聞かれなければ成功です。

cronの実行と設定

crondが起動しているか調べます。デフォルトでは動いていないと思います。

$ service cron status
 * cron is not running

cronを起動しましょう。

$ sudo service cron start
 * Starting periodic command scheduler cron

cronが起動したはずです。

$ service cron status
 * cron is running

あとは適当な頻度、例えば10分おきぐらいにsudo hwclock -sを実行してやればOKです。crontab -eでcronを編集しましょう。

*/10 * * * * /sbin/hwclock -s

crondの起動

さて、WSLのcronは自動起動してくれないので、Windowsを再起動したらcronはまた止まってしまいます。バッチファイルに起動スクリプトを書いてスタートアップに入れてWindows起動時に自動実行させる方法もありますが、実行にroot権限が必要なものを勝手に起動させるのもちょっと気が引けます。そこで、ターミナル起動時にチェックして、起動してなければ実行する形式にしてみましょう。以下を.zshrcに入れておきます。

if [[ -n `service cron status | grep not` ]];then
    echo "cron is not running. Type password to run it."
    sudo service cron start
fi

これで、ターミナルを起動時にcronが起動していなければパスワードが要求され、cronが起動します。

まとめ

WSLでcronを起動し、sudo hwclock -sを定期実行させる環境を作ってみました。やったことは以下の通りです。

  • /etc/sudoersを編集して、sudo hwclockの実行にパスワードを不要にした
  • cronにコマンドを登録してsudo hwclock -sを定期実行させるようにした
  • .zshrcでサービスをチェックし、cronが実行していなければsudo service cron startさせるようにした

僕はターミナル起動時に一度だけパスワード入力するのは良いかな、と思いましたが、Windows起動時にcronを自動実行したい場合は以下の記事を参考にすると良いでしょう。