WSL2で困ったときに使う魔法の呪文

# 絶対だいじょうぶだよ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/554bfd19-848b-bf8c-fe8b-b26e0cf74bb3.png)

引用：[Windows 7、Linuxのリーナス・トーバルズも太鼓判](https://japanese.engadget.com/2009/10/23/windows-7-linux/)

みなさん。WSL2使ってますでしょうか。
WSL2とは2019年5月に「Build 2019」で発表された、Windows Subsystem for Linuxのアップデート版です。
ざっくりというとMS公式が作ったWindows上で動くLinuxです。
正直、こういうものは昔からあり、眉唾ものだったのですが、WSL2あたりから、dockerが正常に動作するようになり、開発環境として常用するようになりました。
そこで、私が半年使ってきた中で、WSL2関連でどういう問題が発生したのか、どういう解決をしたのか。そのあたりを紹介したいと思います。

**それらの問題は、大体1つの魔法の呪文でなんとかなります。**

```powershell
> wsl --shutdown
```

# apt-getが失敗する

> ピーリカピリララ ポポリナペーペルト！

**なんかapt-getが失敗する**

というすごいざっくりとした現象が起こることがあります。
パッケージがないのでは？と思いますが、`apt-cache search`をやってもパッケージが存在する。そして、apt-getを行ったら、たまに起こるパッケージの破損でもない。そんな時は、

```powershell
> wsl --shutdown
```

をすれば直ることがあります。
原因は何か？というと、WSL2の時刻のずれです。時刻がずれていると、apt-getが失敗するそうです。

[Ubuntu 18.04LTSで # apt update 失敗 → 設定変更により、修正完了](
http://kunpu1306.hatenablog.com/entry/2018/10/14/095340)

これは、私のユースケースかもしれませんが、ノートパソコンでWSL2を動かしていました。そのため、ちょこちょことスリープ状態にすることがあり、そこから復帰したときに、失敗することが多かったです(おそらく、電池が切れそうになりPCの動作が極限まで落ちて、WSL2上の時計が止まる？)。そのため、WSL2自体を再起動することで、時刻のリセットをかけ、直していました。

# localhostが見えない　

> ノボブヨ、オシ、ハシタワ、ドケダ、グンミーチャ、デー、リブラ！

さて、最近ではdockerで開発することも多いと思います。

```bash
sudo docker run --rm -it -p 8000:80 ubuntu:latest
```

などポートフォワーディングをすることも多いと思います。**しかし、localhost:8000をブラウザで見てみると表示されない。**
実は、過去にWindows側からWSL上のサーバーへリクエストをする場合、設定が必要でした。

「WSL 2」最大の課題であった“localhost”問題が解決 ～「Windows 10」Build 18945
https://forest.watch.impress.co.jp/docs/news/1198651.html

しかし、そんなことは関係なく、localhostが見えない。という挙動です。
それ以外の理由だと、これだけだと、dockerのimageが壊れているのか？と思われるかもしれませんが、そうでない場合もあります。
WSL2上で、

```
$ curl localhost:8000
```

とすると、正常なレスポンスが返ってきます。意味が分からない。
ざっくりといいますと、**WSL2とWindowsのネットワークのブリッジが悪い。**
ということがあります。これは、WSL2上のポートの8000番はlistenしている状態なのですが、それをWindows側から見ると、8000番が閉じられており、疎通が取れない。ということがあります。
この話のやっかいなポイントとして、開発上3つぐらいポートをバインドしていたときに、1つだけポートがWindowsから見れない。といった中途半端にWSL2-Windows間のポートの疎通が死ぬ場合があり、プログラムのバグと判別がつきにくいことです。そのため、一度でもポートの疎通が取れない場合は、とりあえずWSL2上で、telnetやcurlをお勧めします。そして、WSL2上でレスポンスが返ってくるのに、Windows上から見えないときは、

```powershell
> wsl --shutdown
```

です。


# だんだん動作が遅くなる

> オンキリキリバサラウンバッタ

これは非常にわかりにくいバグなのですが、**特定のコマンドを打った時にメモリリークする。**という挙動です。私の場合は、(おそらく)

```bash
sudo docker build
```

でした。2GB程度のDockerイメージを毎日ガシガシビルドして、動作を調整していた時期があるのですが、そういう作業をしていると、だんだんとWSL2のレスポンスが遅くなり、Chromeの検索窓の入力にもたついたりし始めました。タスクマネージャーを見るとDockerのイメージをビルドするたびにvmmemというプロセスの使用メモリが増えていき、ビルドを終了してもメモリが解放されない。という事象がありました。
入ってたウイルス対策のソフトがMcAfeeだと発生するというIssueがありましたが、別のウイルス対策を入れても、あまりメモリリークには関係ないように見えました。

https://github.com/Microsoft/WSL/issues/3049

こうなると、メモリ食いつぶすだけで、メモリの使用量の上昇を止める方法がないので、いつものやつです。

```powershell
> wsl --shutdown
```

# 突然ディレクトリが見えなくなる

> エロイムエッサイムエロイムエッサイム

WSL2上で、以下のコマンドを打ってみてください。

```bash
$ cd ~
$ explorer.exe .
```

そうすると、普通にエクスプローラーが起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/6632461d-1eaa-da93-25dc-a2a8038e4894.png)

WSL2のキモイポイントですが、**WSL2上のUbuntuのBashからWindowsのexeが普通に呼べます。**
したがって、explorer.exeによって、Ubuntu上のフォルダの中身を閲覧することができます。
しかし、このフォルダは突然見えなくなることがあります。この場合だと、

「\\wsl$\Ubuntu\home\kotauchisunsunのパスは存在しません。」

のようなエラーが発生することがあります。このエラーが出るタイミングがよくわからず、PCをスリープから復帰したタイミングというわけでもなく、割とランダムに1日1回ぐらいのペースででたりします。はい。直し方はわかりません。なので、

```powershell
> wsl --shutdown
```

# ファイルが突然なくなる

> いあ！いあ！くとぅるふ ふたぐん！

これはWSL1の時代にあった話なのですが、WSL2でも応用できる面がありそうなので書いておきます。
題名は怖い内容ですが、いきなりファイルをぶっ壊すわけではありません。しかし、非常に困った挙動をする場合があります。
VueやReactなどの開発をしている場合、ファイルの変更を検知し、ホットリロードをかける場合があると思います。例えば、Vueの場合、

```bash
$ npx vue-cli-service serve
```

などです。
普通に開発をしてると、`xxxx.js not Found.`的なエラーが発生し、あれ？なんか間違って消したっけ？と思って、`ls xxxx.js`とか打ってみると、普通に存在するわけです。**lsでは見えるけども、ホットリロードからは見えなくなる**的な割とやらしいバグが発生したりします。

この原因なのですが、おそらく**Windows側のファイルシステムの方式により発生するバグ**だと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139643/f8509c9d-f425-3045-6d44-8b04ce53695b.png)

画像元　[Build 2019で見えた「Windows Subsystem for Linux 2」の詳細](https://ascii.jp/elem/000/001/860/1860575/2/)

WSL1からCドライブ配下のファイルを見るときにはDrvFsという方式で見ています。先ほどのファイルがなくなる現象が発生したときは、C:\配下にファイルを置いていたので、このDrvFsという形式でアクセスしており、おそらく、それが見えなくなる原因だったんだろうと思います。
それが、WSL2になり、C:\配下領域は9P、WSL2領域はext4で見るようになっています。

[Windows10 Insider 18917 で WSL2 が来たので雑にボリュームマウントのベンチマークとってみた（追記あり)
](https://qiita.com/kunit/items/051196022763e64e91f6)

参考記事を見てもらうとわかるのですが、**git cloneの場合、C:\配下やる場合と、~/でやる場合、前者の方が3倍程度遅いです。**これは、マウントしている方式の違いです。
先述したようにこの"ファイルが見えなくなるバグ"はWSL1の時に起きたバグで、WSL2では起きていません。理由としては、自分が、必ず~/配下にファイルを置くようにしたからで、/mnt/c/配下にファイルを置いていないからかもしれません。
なんやかんや/mnt/c/以下のフォルダに置く方がデバッグ効率や利便性が高かったりすると思いますが、

**/mnt/c/以下だと9pの方式でマウントされ、それ由来のよくわからないバグをひく可能性があり、そもそもアクセス速度も遅いので、おとなしく~/以下にファイルを置く方が下手なバグにあたる可能性が低いです。**

<!--- https://hanocha.hateblo.jp/entry/2019/06/18/001136 -->
<!--- https://news.mynavi.jp/article/20190620-845374/ -->


# Dockerがrunできない

> もう何も恐くない

すごい雑なことを言いますが、

**WSL2上で実行するファイルをSourceTreeなどのWindowsのGitクライアントで管理しない方がいい**

おとなしくコマンドラインのWSL2上のgitを使うことをお勧めします。
これは、同僚に「WSL2でとりあえず開発できるよ。」と言って、任せたのですが、どうも開発環境が動かない。という話をされました。挙動を聞くと、docker-composeが動かない。と言うのです。
そういうバグは何度かあたってきているのですが、普通にcheckoutしたばかりのファイルが動かない。ということは、どうも理屈に合わない。
以前、自分がdocker-composeが動かなかったときは、**dockerに含まれるファイルにCR+LFが改行コードが含まれていると動かない。**という挙動でした。
で、話を聞いてみると、WindowsのGitでコードをチェックアウトした。という話でした。どうやら**改行コードをCR+LFに書き換えるGitクライアントがいるようです。**実際に、はまってらっしゃる方も居られます。

[Windowsでcodeceptionをbuildする際は改行コードに注意](https://qiita.com/okazy/items/8ce003fbb54e798b4af7)

そのため、無用なバグで時間をつぶしたくない場合は、おとなしくWSL2のgitでコマンドラインでcheckoutをお勧めします。




# 感想
Windows上でネイティブのLinuxが動く。という思想自体、結構昔からありました。私が知っている中では、SUAですかね。

[UNIX互換環境を実現するSUA（Subsystem for UNIX-Based Application）を利用する](https://www.atmarkit.co.jp/ait/articles/1102/04/news120.html)

LinuxはUnixじゃない！いや！SUAはPOSIXの認可を取っているから、実はWindowsはUnixなんだ！！みたいなめんどくさい話はあるんですが、当時は全然使いませんでした。私に使いこなせる技術力がありませんでした。
昔はMSはOSSからEvil的な扱いをされていましたが、本当に時代は変わるものです。
しかし、WSL2はいろいろ使いやすいです。Bash使えると本当に便利。