WSL上のcronで時刻を定期的に修正する
はじめに
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を自動実行したい場合は以下の記事を参考にすると良いでしょう。
Discussion