目次

編集中

WSL2 LinuxとのWindowsの相互運用性

y2sunlight 2020-12-10

WSL2に戻る

関連記事

リンク


ファイルアクセス

WindiswからLinuxのファイルをアクセスする

以下の形式で、WindiswからLinux上のファイルをアクセスできます:

\\wsl$\{distribution name}\{path}

実行例

PS C:\> dir \\wsl$\Ubuntu-20.04\
 
    ディレクトリ: \\wsl$\Ubuntu-20.04
 
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2020/12/11      8:57                home
d-----        2020/08/05      6:39                srv
d-----        2020/12/24     13:54                etc
d-----        2020/08/05      6:39                opt
d-----        2020/12/11     23:40                root
d-----        2020/12/11      8:57                mnt
d-----        2020/08/05      6:40                usr
...


LinuxからWindiswのファイルをアクセスする

以下の形式で、LinuxからWindisw上のファイルをアクセスできます:

/mnt/{drive name}/{path}

実行例

$ ls /mnt/c/Users -l
total 0
lrwxrwxrwx 1 root root  18 Dec  7  2019 'All Users' -> /mnt/c/ProgramData
dr-xr-xr-x 1 root root 512 Dec 18 23:44  Default
lrwxrwxrwx 1 root root  20 Dec  7  2019 'Default User' -> /mnt/c/Users/Default
drwxrwxrwx 1 root root 512 Dec 18 23:29  Public
-r-xr-xr-x 1 root root 174 Dec  7  2019  desktop.ini
drwxrwxrwx 1 root root 512 Dec 18 23:55  y2sunlight


ネットワークアクセス

WLS2の仮想ネットワーク

WSL2は、Hyper-Vが管理する仮想マシン環境で動作します。このとき物理ハードウェアの上で動いているOSをホストOS、仮想マシン内で動作しているOSをゲストOSと呼ぶ事にします。そして、ホストマシンには物理NICが、仮想マシンには仮想NICが提供されています。

ホストマシンとゲストマシンの間にはHyper-Vの仮想ネットワークが構築されます。この仮想的ネットワークは、ホストマシンと仮想マシンが共に接続した状態を作ります。

WSL2を起動すると、「vEthernet(WSL)」という仮想ネットワークに接続するホスト側のネットワークアダプター(NIC)が作られますが、仮想ネットワークを構成している仮想スイッチは、ホストOSのネットワーク機能で見ることはできません。

仮想ネットワークのIPアドレスはプライベートアドレスが割り当てられ、ホストOSの再起動によって変更されます。

複数のWSL2ディストリビューションは同じネットワーク名前空間を使用し、ネットワークの分離はありません。参考 https://github.com/microsoft/WSL/issues/4304

WSL2のリスニングポート

WSL2では、仮想マシン側でリスニングされているポート番号と同じポート番号を、ホスト側で動作しているwslhost.exeがリスニングします。

例えば、仮想マシン側でポート80をリスニングしていると、ホスト側でも wslhost.exe がポート80をリスニングします。そして、 wslhost.exe は、受け取ったパケットを仮想ホスト側の同じポート番号に転送します。つまり、ホスト側がlocalhostの(仮想ホスト側がリスニングしていると同じ)ポート番号にアクセスすると、仮想ホスト側のネットワークサービスからは、eth0からのアクセスのように見えます。

localhost

IPv4では、ネットワークアドレス 127.0.0.0 が localhost の数値表現として扱われ、慣例的に末尾 1 の 127.0.0.1 を自分自身のIPアドレスの名前として使用されます。localhostという名前は、どんな名前解決システムも使うことなく 127.0.0.1 に解決で出来ます。IPv6では、::1 だけが localhost の数値表現として扱われ、IPv4のようにlocalhostはホスト名でありネットワークの表現ではありません。

WSL2が稼働しているとき、仮想マシン上の特定のポート番号をリスニングしている、HTTPサーバなどのTCP/IPアプリケーションに対して、ホストマシン側からは、localhost を接続先として指定すれば( http://localhost:<ポート番号>/ )、そのアプリケーションにアクセスすることが出来ます。


WLS2側からWindows側のネットワークにアクセスする

TODO:


Windows側からWLS2側のネットワークにアクセスする

TODO:


WindowsからのLinuxコマンドを実行する

デフォルトのディストリビューション

Windows から Linux のコマンドを実行する場合、特に指定しなければデフォルトのディストリビューションが対象になります。デフォルトのディストリビューションを調べるには、以下のようにします:

実行例:

PS C:\Users\sunlight> wsl -l -v
  NAME              STATE           VERSION
* Ubuntu-20.04-2    Running         2
  CentOS7.6         Running         2
  Ubuntu-20.04      Stopped         2

以下のようにすれば、デフォルトのディストリビューションが変更できます:

wsl -s {distribution name}


Linux のコマンドの実行

wsl コマンドを使って、次の形式で Windows のコマンドプロンプト(cmd) または PowerShell から Linux のコマンドを実行できます。

wsl {Linux command}

また、 ディストリビューションやユーザを指定してコマンドを実行するには:

wsl -d {distribution name} -u {user name} {Linux command}

実行例1:簡単な例

PS C:\Users\sunlight> wsl ls -l
lrwxrwxrwx 1 root root       66 Dec 18 23:34 スタート メニュー -> /mnt/c/Users/sunlight/AppData/Roaming/Microsoft/Windows/Start Menu
drwxrwxrwx 1 root root      512 Dec 18 23:45 3D Objects
drwxrwxrwx 1 root root      512 Dec 18 23:35 AppData
lrwxrwxrwx 1 root root       37 Dec 18 23:34 Application Data -> /mnt/c/Users/sunlight/AppData/Roaming
...

実行例2:ユーザを指定

PS C:\Users\sunlight> wsl whoami # ユーザを指定しない場合
root
PS C:\Users\sunlight> wsl -u y2sunlight whoami # ユーザを指定する場合
y2sunlight

実行例3:ディストリビューションとユーザを指定

PS C:\Users\sunlight> wsl -d CentOS7.6 -u y2sunlight cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

実行例4:dockerサービスを起動してコンテナを開始する

PS C:\Users\sunlight> wsl sudo service docker start
 * Starting Docker: docker [ OK ]
PS C:\Users\sunlight> wsl docker start myphp73
myphp73

実行例5-1:PowerShellコマンドとLinuxコマンドの組み合わせ

PS C:\Users\sunlight> netstat -an|wsl grep 8080
  TCP         [::1]:8080             [::]:0                 LISTENING

実行例5-2:PowerShellコマンドとLinuxコマンドの組み合わせ

PS C:\Users\sunlight> wsl netstat -an|Select-String 8080
tcp6       0      0 :::8080                 :::*                    LISTEN
wsl netstat はLinux側のポートを見ている点に注意して下さい。確認の為、wsl netstatnetstat の両方をそのまま実行してその違いを比べる事ができます。

実行例6:複雑なコマンドを実行する

PS C:\Users\sunlight> wsl -d Ubuntu-20.04-2 -u root bash -c "service docker start && docker start myphp73"
 * Starting Docker: docker [ OK ]
myphp73


bashターミナルに切り替える

Windowsのコマンドプロンプト(cmd) または PowerShell から bash ターミナルに切り替えるには bash コマンドを使用します:

PS C:\Users\sunlight> bash

bash コマンドには、ディストリビューションやユーザのオプション指定がないので、その場合は、wsl コマンドを使用します。実行例:

PS C:\Users\sunlight> wsl -d CentOS7.6 -u y2sunlight bash


LinuxからのWindowsコマンドを実行する

Windowsのコマンドの実行

次のようにして、LinuxからのWindowsコマンドを実行できます:

{command name}.exe

実行例1:簡単な例

$ hostname.exe # コンピュータ名の取得
zeus2

実行例2:Windows側のIPアドレスの取得

$ ipconfig.exe
 
Windows IP 構成
 
イーサネット アダプター イーサネット:
 
   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: fe80::a058:d977:ab7:9f83%7
   IPv4 アドレス . . . . . . . . . . . .: 192.168.11.18
   サブネット マスク . . . . . . . . . .: 255.255.255.0
   デフォルト ゲートウェイ . . . . . . .: 192.168.11.1
 
イーサネット アダプター vEthernet (WSL):
 
   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: fe80::2858:9897:3574:179e%20
   IPv4 アドレス . . . . . . . . . . . .: 172.26.144.1
   サブネット マスク . . . . . . . . . .: 255.255.240.0
   デフォルト ゲートウェイ . . . . . . .:

実行例3:WindowコマンドとLinuxコマンドの組み合わせ

$ ipconfig.exe | grep IPv4
   IPv4 Address. . . . . . . . . . . : 192.168.11.18
   IPv4 Address. . . . . . . . . . . : 172.26.144.1

実行例4:コマンドプロンプト(cmd.exe)の内部コマンド

~$ cmd.exe /c ver
'\\wsl$\Ubuntu-20.04-2\home\y2sunlight'
上記の現在のディレクトリで CMD.EXE を開始しました。
UNC パスはサポートされません。Windows ディレクトリを既定で使用します。
 
Microsoft Windows [Version 10.0.19041.685]

実行例5:WindowのGUIアプリを起動する

$ notepad.exe    # フォアグラウンドで実行
$ notepad.exe &  # バックグランドで実行


Windowsのターミナルに切り替える

コマンドプロンプト(cmd)に切り替える:

$ cmd.exe

Power Shellに切り替える:

$ powershell.exe

何れの場合も、exit コマンドで終了してLinuxターミナルに戻ります。


環境変数の共有

WSL2には、Windows と Linux の両方で使用できる環境変数 WSLENV があります。WSLENV はWindows と Linux の双方で共有される特殊な環境変数です。

PowerShell:

PS C:\Users\sunlight> echo $env:WSLENV
WT_SESSION::WT_PROFILE_ID

Bash:

$ echo $WSLENV
WT_SESSION::WT_PROFILE_ID

WSLENV の内容は、Windows と Linux の間で引き継ぎたい環境変数が : で区切られて列挙されています。例えば上の例の、WT_PROFILE_ID を双方のシェルで確認してみると以下のようになっています。

PowerShell:

PS C:\Users\sunlight> echo $env:WT_PROFILE_ID
{61c54bbd-c2c6-5271-96e7-009a87ff44bf}

Bash:

$ echo $WT_PROFILE_ID
{048a85e4-0278-5ae1-8add-531a3d3eb4ac}

環境変数 WT_PROFILE_ID の内容は、ディストリビューションのGUIDです。

以下のタイミングで環境変数の引継ぎが行われます:

この相互運用性は地味なものに見えますが、WindowsとLinuxの双方でシームレスにデータを利用するアプリケーションにとっては非常に便利な機能だと思います。本編では、WSLENV についての説明は、紹介程度に留めておきたいと思います。詳細は以下を参照して下さい: