WSL (Windows Subsystem for Linux)の基本メモ

# 概要

Windowsでちょっとしたシェルスクリプトを書いて試したり、コマンドの使い方やmanページを見たい時にWSLでLinux環境を用意しておくと便利でした。Docker Desktop for Windowsでも同様のことはできると思いますが、WSLは起動が早いのでお手軽です。
なお、WSLを利用するには先にWSLの有効化を行っておく必要がありますがこの記事では割愛します。

**環境**

* Windows 10 Professional 1809

**参考**

* [【WSL入門】第1回　Windows 10標準Linux環境WSLを始めよう] (https://www.atmarkit.co.jp/ait/articles/1903/18/news031.html)
* [Windows Subsystem for Linux に関するドキュメント] (https://docs.microsoft.com/ja-jp/windows/wsl/about)
* [Windows Command Line Tools For Developers] (https://devblogs.microsoft.com/commandline/)

# Ubuntuのインストール

インストールはMicrosoft Storeから行います。検索フィールドに"Ubuntu"と入力して検索すると現時点(2019/05)では3つ(Ubuntu, Ubuntu 18.04 LTS, Ubuntu 16.04 LTS)検索できました。通常はバージョンの表記が無いUbuntuでいいようですが、今回はUbuntu 18.04 LTSを選択しました。

インストールをはじめるとターミナルが立ち上がり
![wsl_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/eb867e03-04c2-a33c-950f-4020f107a54f.png)
下図のようにUnix usernameとpasswordの設定を求められます。username, passwordを決めるとWSL上のUbuntuが利用できるようになります。
ここで決めたパスワードはsudoコマンドを実行するときに必要になります。
![wsl_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/951ff2fd-db0f-acc8-ec25-10b7fcf67a1e.png)

以降のUbuntuの起動は、スタートメニューに登録されているUbuntuをクリックするか、コマンドプロンプトからwsl.exeもしくはbash.exeを実行します。

**バージョン確認**

```bash
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
```

## インストール後の作業

Ubuntuインストール後に以下の作業を行いました。

パッケージリストの更新

```bash
$ sudo apt update
```

パッケージのアップグレード

```bash
$ sudo apt upgrade -y
```

[WSLのUbuntu環境を日本語化する] (https://www.atmarkit.co.jp/ait/articles/1806/28/news043.html)を参考に日本語化します。

日本語言語パックのインストールとロケールの設定

```bash
$ sudo apt install -y language-pack-ja
$ sudo update-locale LANG=ja_JP.UTF-8
```

タイムゾーンの設定、日本語のmanpageをインストール

```
$ sudo dpkg-reconfigure tzdata
$ sudo apt install -y manpages-ja manpages-ja-dev
```

日本語化した後に文字化けを起こす場合は、日本語を表示できるフォントが使われているか確認します。
（文字化けしたのでMigu 1Mに変更しています。）
![font.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/4e1dfa6c-4652-feef-8fae-46516f4cf767.png)

### rootユーザ

rootユーザになる必要はほとんどありませんが、次のコマンドでrootユーザになることができます。

```bash
$ sudo su -
```

**ユーザの追加**

インストール時に決めたユーザだけで十分だと思いますが、新しいユーザを追加し、そのユーザでディストリビューションを起動させることもできます。

```bash
$ sudo adduser test1
Adding user `test1' ...
Adding new group `test1' (1001) ...
Adding new user `test1' (1001) with group `test1' ...
Creating home directory `/home/test1' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for test1
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n]
```

## その他もろもろ

### cron

cronも使えますが、使うにはcronのサービスをスタートさせる必要があります。

```bash
$ sudo service cron status
 * cron is not running
$ sudo service cron start
 * Starting periodic command scheduler cron
```

### openjdk

```bash
$ sudo apt install -y openjdk-11-jdk
$ java --version
openjdk 11.0.2 2019-01-15
OpenJDK Runtime Environment (build 11.0.2+9-Ubuntu-3ubuntu118.04.3)
OpenJDK 64-Bit Server VM (build 11.0.2+9-Ubuntu-3ubuntu118.04.3, mixed mode, sharing)
```

### vim

```bash
$ sudo apt install -y vim
$ vim --version
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Apr 10 2018 21:31:58)
... 省略 ...
```

### curl

```bash
$ sudo apt install -y curl
$ curl --version
curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.0g zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3
Release-Date: 2018-01-24
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL
```

### jq

```bash
$ sudo apt install -y jq
$ jq --version
jq-1.5-1-a5b5cbe
```

### nkf

```bash
$ sudo apt install -y nkf
$ nkf --version
Network Kanji Filter Version 2.1.4 (2015-12-12)
Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).
Copyright (C) 1996-2015, The nkf Project.
```

## WSL上のディストリビューションのファイルシステムにWindowsからアクセス

エクスプローラから`\\wsl$`という名前でアクセスすることができます。WSLが起動していると図のようにディストリビューション名が表示されています。（WSLが起動していないと表示されません）
![wsl1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/ec6e40a3-8486-64c6-4320-7758246d9742.png)

![wsl2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22772/409d6d19-6349-fb1e-2925-b2763cf2ea34.png)

※下記の方法でアクセスするとWSL側のファイルシステムの状態に矛盾が起きる可能性があるため禁止されています。

~~Windowsからアクセスしない方がいいと（保証されているか不明なので）思いますが、Ubuntuの場合は下記のディレクトリにディストリビューションのファイルシステムが格納されています。
（CanonicalGroupLimitedはUbuntuの開発元のCanonical Ltd.のことか?）~~

```text
C:\Users\{USERNAME}\AppData\Local\Packages\CanonicalGroupLimited.{ディストリビューション固有の文字列}
      |
      `--- \LocalState
                |
                `--- \rootfs
                        |
                        `--- \bin
                        `--- \boot
                        `--- \dev
                        `--- \etc

                        ... 省略 ...

                        `--- \tmp
                        `--- \usr
                        `--- \var
```

## WindowsのファイルシステムにWSL上のディストリビューションからアクセス

Windowsのドライブレターが/mnt下にマウントされています。

```bash
$ cd /mnt
$ ls -l
total 0
drwxrwxrwx 1 rubytomato rubytomato 512 May 17 18:08 c
drwxrwxrwx 1 rubytomato rubytomato 512 May 17 18:08 d
```

このマウントは`/etc/wsl.conf`ファイルでコントロールできます。
デフォルトではこのファイルは存在しませんが、以下のデフォルト値が適用されています。
マウントしたくない場合はautomountセクションのenabledをfalseに設定しwslを再起動します。

* 参考: [Manage and configure Windows Subsystem for Linux] (https://docs.microsoft.com/en-us/windows/wsl/wsl-config)

```text:default
[automount]
enabled = true
root = /mnt/
options = ""
mountFsTab = true

[network]
generateHosts = true
generateResolvConf = true

[interop]
enabled = true
appendWindowsPath = true
```

### シンボリックリンクの作成

例えばWindowsの`D:\ubuntu_work`というディレクトリにworkというシンボリックリンクを作成するには以下のようにします。

```bash
$ ln -s /mnt/d/ubuntu_work ./work
$ ls -laF work
lrwxrwxrwx 1 rubytomato rubytomato 18 May 17 23:54 work -> /mnt/d/ubuntu_work/
```

Windowsのエクスプローラーでtest.txtというファイルを作成すると、Ubuntu側では以下のように見えます。

```bash
$ ls -l
total 0
-rwxrwxrwx 1 rubytomato rubytomato 24 May 17 22:35 test.txt
```

# Windowsツール

WSL用のWindowsツールがあります。

## WSL構成ツール (wslconfig.exe)

インストールしたディストリビューションを管理します。
UbuntuとArch Linuxをインストールした状態で確認すると、下記のように出力されます。

```
> wslconfig /l
Windows Subsystem for Linux ディストリビューション:
Ubuntu-18.04 (既定)
ArchLinux
```

下記のコマンドで、デフォルトのディストリビューションをArch Linuxに変更します。

```
> wslconfig /s ArchLinux
> wslconfig /l
Windows Subsystem for Linux ディストリビューション:
ArchLinux (既定)
Ubuntu-18.04
```

```text:help
Linux 用 Windows サブシステムの管理操作を実行します

使用法:
    /l, /list [/all]
        登録されたディストリビューションを一覧表示します。
        /all - すべてのディストリビューションを一覧表示します (オプション)。
               現在インストールまたはアンインストール中のものも含まれます。

    /s, /setdefault <ディストリビューション名>
        ディストリビューションを既定として設定します。

    /t, /terminate <ディストリビューション名>
        ディストリビューションを終了します。

    /u, /unregister <ディストリビューション名>
        ディストリビューションの登録を解除します。

    /upgrade <ディストリビューション名>
        ディストリビューションを WslFs ファイル システム形式にアップグレードします。
```

## WSLランチャー (wsl.exe)

名前の通りランチャーです。WSLのディストリビューションを起動します。

ユーザを指定しない場合、デフォルトのディストリビューションにインストール時に作成したアカウントでログインします。

```
> wsl
```

デフォルトのディストリビューションに-uオプションで指定したアカウントでログインします。

```
> wsl -u rubytomato
```

-dオプションで指定したディストリビューションに-uオプションで指定したアカウントでログインします。

```
> wsl -d Ubuntu-18.04 -u rubytomato
```

```text:help
使用法: wsl.exe [オプション] ...
オプション:
    -d, --distribution <ディストリビューション名>
        指定したディストリビューションを起動します。

    -e, --exec <コマンド ライン>
        指定した Linux コマンドを実行します。残りの引数は
        実行するコマンド ラインとして使用されます。

    -u, --user <ユーザー名>
        指定したユーザーとして実行します。

    --help
        この使用法の情報を表示します。

    --
        引数の解析を停止し、残りの引数を Linux プロセスに渡します。
```

## Bashランチャー (bash.exe)

WSLの一部かどうかは不明ですが、Bashランチャーというものもあります。
wsl.exeと同様にWSLのディストリビューションを起動します。

```
> bash
```

# 補足

## ターミナルにHyperを利用する

* [Hyper™] (https://hyper.is/)

HyperはElectron製のマルチプラットフォーム(macOS、Windows、Linux distros)で使用できるターミナルソフトです。
インストールは簡単でサイトからインストーラ(今回は`hyper-Setup-3.0.2.exe`)をダウンロードしてインストールするだけです。

インストール直後はcmd.exeが開くようになっているので、設定ファイルを編集してWSLのBashランチャーで開くようにします。
Hyperを起動しハンバーガーメニューから`Edit` → `Preferences...`を選択、または<kbd>Ctrl + ,</kbd>を押下します。
`.hyper.js`というファイルが開くので下記の箇所を書き換えてリロードします。

```
shell: 'C:\\Windows\\System32\\bash.exe',
```

### プラグイン

プラグインをインストールして機能を拡張することができます。
プラグインは[Hyper Store - Plugins] (https://hyper.is/plugins)で検索することができ、インストールは`.hyper.js`というファイルにプラグイン名を記述することで自動的に導入されます。
また、プラグインの他にテーマもありプラグインと同じ方法で導入できます。

今回は下記2つのプラグイン／テーマを導入してみました。

* [hyper-opacity] (https://hyper.is/plugins/hyper-opacity)
* [hyper-material-theme] (https://hyper.is/plugins/hyper-material-theme)

```
plugins: [
    'hyper-material-theme',
    'hyper-opacity'
],
```

hyper-opacityは`.hyper.js`で設定を変えることができます。下記のようにウィンドウがフォーカスされているときとされていないときのopacityを変えることができます。

```
config: {
    opacity: {
        focus: 0.8,
        blur: 0.4
    },

    // for advanced config flags please refer to https://hyper.is/#cfg
},
```

## ターミナルにWindows Terminalを利用する

『[Windows Terminal (Preview) メモ] (https://qiita.com/rubytomato@github/items/e88cab84f36e44797cf2)』という記事を作成しました。