編集中
— y2sunlight 2020-12-10
関連記事
リンク
以下の形式で、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上のファイルをアクセスできます:
/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
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では、仮想マシン側でリスニングされているポート番号と同じポート番号を、ホスト側で動作しているwslhost.exeがリスニングします。
例えば、仮想マシン側でポート80をリスニングしていると、ホスト側でも wslhost.exe がポート80をリスニングします。そして、 wslhost.exe は、受け取ったパケットを仮想ホスト側の同じポート番号に転送します。つまり、ホスト側がlocalhostの(仮想ホスト側がリスニングしていると同じ)ポート番号にアクセスすると、仮想ホスト側のネットワークサービスからは、eth0からのアクセスのように見えます。
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:<ポート番号>/ )、そのアプリケーションにアクセスすることが出来ます。
TODO:
TODO:
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
Ubuntu-20.04-2
がディストリビューションです。以下のようにすれば、デフォルトのディストリビューションが変更できます:
wsl -s {distribution name}
wsl コマンドを使って、次の形式で Windows のコマンドプロンプト(cmd) または PowerShell から Linux のコマンドを実行できます。
wsl {Linux command}
wsl -e {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
wsl sudo service docker start && docker start myphp73
実行例5-1:PowerShellコマンドとLinuxコマンドの組み合わせ
PS C:\Users\sunlight> netstat -an|wsl grep 8080 TCP [::1]:8080 [::]:0 LISTENING
|
)の左がPowerShell、右がLinuxコマンドです。実行例5-2:PowerShellコマンドとLinuxコマンドの組み合わせ
PS C:\Users\sunlight> wsl netstat -an|Select-String 8080 tcp6 0 0 :::8080 :::* LISTEN
|
)の左がLinuxコマンド、右がPowerShellです。|
)はPowerShellが支配しています。wsl netstat
はLinux側のポートを見ている点に注意して下さい。確認の為、wsl netstat
とnetstat
の両方をそのまま実行してその違いを比べる事ができます。
実行例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
の -c
オプションを使って複雑なLinuxコマンドを実行しています。-u root
は不要ですが、sudo
していないので明示しました。
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コマンドを実行できます:
{command name}.exe
UTF-8
の環境下で実行されます。cmd.exe
)の内部コマンド cmd.exe /c {command}
と指定します。\
でエスケープするか、引用符で囲みます。cmd.exe /c dir D:\\
実行例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 & # バックグランドで実行
コマンドプロンプト(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
についての説明は、紹介程度に留めておきたいと思います。詳細は以下を参照して下さい: