Windows Subsystem for Linux(以下WSLとする)は、RS3で正式版となり、動作が変更になった。ベータ版のときには、bash.exeが唯一の起動方法で、Linux本体をlxrun.exeで管理していたが、Linuxディストリビューション(現時点ではubuntuとSUSE)がWindowsストアからのダウンロード、インストールとなり、lxrun.exeはRS2までのWSLの管理用となった。なおRS2では、bash on Windowsなどの名称があったが、RS3からはWindows Subsystem for Linuxが正式名称となっている。
ちなみにLinuxでは、タスクよりもプロセスという用語が好まれる。ただし、一般的にタスクとプロセスの区別は明確でない(Linuxでもプロセスに対応するカーネル内の構造体にはtaskという名称が使われている)。ただし、プロセスはスレッドとの対応で、比較的範囲が狭く、プロセスやスレッド(さらにはファイバ)などの実行単位をまとめてスレッドと呼ぶことが比較的多い。ここではこの意味でタスクを使うことにして、「バックグラウンドタスク」と表現することにする。
RS3でWSLを起動する方法はwsl.exeとなった。ただし、起動方法は3つある。
1つは、このwslコマンドで、ディストリビューション名を使った「ubuntu.exe」というコマンドも用意された。ただし、これについてはwsl.exeを介してWSLを起動しているようだ。最後の1つは、ベータ版のときと同じbash.exeである。bash.exeの場合は、RS2までと同じく直接WSL環境を起動するようだ。なお、wslコマンドでは、インストールされているディストリビューションのうち1つをデフォルトとしてwslconfig.exeで指定するが、ディストリビューション名を使ったコマンドでは、wslconfigの設定にかかわらず、指定のディストリビューションをWSLで起動する。
これらの3つのコマンドの違いだが、wsl.exeとbash.exeは、起動時のカレントディレクトリでそのままWSLが起動するのに対して、ubuntu.exeなどのディストリビューション用コマンドでは、各ユーザーのホームディレクトリ(/home以下)でWSLが起動する。また、wsl.exeとbash.exeは、引数がそのままbashに渡されるのに対して、ディストリビューション用コマンドは、起動オプションがあり、Linuxへのログインユーザー名や実行コマンドなどを指定できる。
なお、現時点でWindowsストアで入手可能なディストリビューションには、
ubuntu 16.04 LTS
openSUSE Leap 42
SUSE Linux Enterprise Server 12
の3つがあり、以下のコマンドで起動が可能だ。
ubuntu.exe
openSUSE-42.exe
SLES-12.exe
これらのコマンドは、where.exeによれば、
%userprofile%\AppData\Local\Microsoft\WindowsApps\
に存在していることになっているが、ここには、ファイルサイズゼロの実行ファイルしかなく、実体は、UWPアプリのインストールフォルダである「C:\Program Files\WindowsApps」以下にWSL用の各ディストリビューションのインストール先フォルダがある。たとえば、ubuntu.exeは、以下のフォルダにある。
C:\Program Files\WindowsApps\CanonicalGroupLimited.UbuntuonWindows_1604.2017.922.0_x64__79rhkp1fndgsc
これは、Desktop Bridgeの仕組みを利用しているとみられ、前記のユーザーフォルダ以下には、他のAppxパッケージ化されたデスクトップアプリケーションの実行ファイルも置かれている。
もともとUWPでは、インストール先フォルダや実行ファイルの実体をみせない(COMを介して起動するため、アプリケーション本体を直接指定しての起動が不可能)ようになっていたが、Desktop Bridgeでは、同じやり方でデスクトップアプリケーションをインストールするようになった。
しかし、デスクトップアプリケーションでは、exe実行ファイルを直接指定して起動し、フルパスを指定しない場合には、PATH環境変数に実行ファイルを含むフォルダーを設定する必要がある。このため、Desktop Bridgeでも同じようにEXE実行ファイルを見せる必要があり、そのためのフォルダとなっている。
RS3でWSLを起動すると、bash.exeやwsl.exeにより、LxssManagerというサービスが起動し、Linuxカーネルの役割を果たすinit.exeが起動し、WSL実行環境が動作しはじめる。起動されるbashは、サブシステムプロセスの中で起動するが、Windowsからは、単独のプロセスのように表示される。もっとも、Windowsでは、プロセスの親子関係を「公式」には認めていない(文書化されていない情報を使うことで親プロセスのPIDは取得できる)。このため、親がわからないプロセスがあっても問題はない。
RS3の3つの方法でWSLを起動したときの様子が下の画面だ。
これはプロセスエクスプローラーを管理者権限で動作させた場合もの。コンソールからubuntu.exeを実行すると、wsl.exeが起動する。しかし、bash.exeの場合にはwsl.exeは起動していない。どの場合もsvchost.exe経由でlxssManagerが起動し、その下でinitが起動している。
これに対して、現在プレビューが進んでいるRS4では、WSLの起動メカニズムが変更になっている。まず、どのコマンドを使っても、wslhost.exe(C:\Windows\System32\lxss)というプログラムが起動してWSL環境を立ち上げるようだ。さらにwslhost.exeは子プロセスとしてconhost.exe(コンソールウィンドウの動作を定義したプログラム)を起動している。ただしウィンドウハンドルは、親となるプロセス(たとえば、cmd.exe)が所有しているようだ。
また、LxssManagerから起動されるinitは、コンソールを起動すると2つ親子で起動され、バックグラウンドタスクがある間はそのうちの1つが残り続ける。このあたりの動作をプロセスエクスプローラーで見たのが下の画面である。
まず、どの場合にも、wslhost.exeが起動している。その前の部分は、RS3と同じく、WSL.EXE(wslコマンドで起動した場合)か、ディストリビューション用コマンド+WSL.EXE、あるいはbash.exeである。
また、wslhost.exeは、さらに子プロセスとしてconhost.exeを起動している。これはWSL内でコンソールを独自に管理しているからと考えられる(このあたりについては次回、もう少し深く見る予定)。また、LxssManagerが起動されるのは同じだが、そこから起動されるinitが2段階となっている。
ここで、バックグラウンドで動作するデーモンの1種であるsshd(ただし、事前にopen-sshのインストールが必要)を起動してみる。起動スクリプトは/etc/init.dにあるので、
sudo /etc/init.d/ssh start
とすると、デーモンとしてsshdが起動する。
この状態で、exitを使ってWSLを抜け、cmd.exeに戻ると、下の画面のような状態になる。このとき、
・LxssManagerから起動されたinitは最初に起動されたもののみとなる
・wslhost.exeは、親のないプロセスとなり実行を続ける(wslhost.exeのpidは変わらない)
initは起動しているため、WSL環境は維持されている。また、この状態になったら、wsl.exeを実行したコンソールウィンドウ(cmd.exeが動作している)を終了させても環境が維持されsshdは動作し続ける。しかし、sshdを終了させるとwslhost.exeも終了する。逆にsshdを動かしたまま、再度wslコマンドを使ってコンソール内でbashを動作させると、新たにwslhost.exeが起動し、sshdを起動したときのwslhost.exeはそのまま残る。
Linuxでは、デーモンとして起動したプロセスは、起動したユーザーではなく、管理者となるrootのプロセスとして動作し、コンソールデバイス(Linux/Unixではttyという)とは無関係のプロセスとなる。このため、起動したユーザーがログアウトしてしまっても、デーモンプログラムは動作し続けることになる。
RS3までは、ユーザーがbashから抜けた段階でWSL環境自体が消えてしまっていたため、実行を継続することができなかった。しかし、RS4では、コンソールと結びついていないプロセスの実行が継続できるよう、wslhost.exeが間に入り、最後のプロセスがなくなるまでWSL環境を維持しつつけていると考えられる。
さて、このバックグラウンドタスクの使い方だが、デーモンの起動に必要なroot権限を考えると、パスワードの手入力が必要となるため、dhcpやdns、sshといったネットワークサービスを起動するのにはあまり向いていない。とはいえ、ローカルでのテスト用にhttpサーバーを起動するといった使い方はありえるだろう。
一つ考えられるのは、WSLで動作しているLinuxをシェルとしてcmd.exeやpowershellといったWindowsのコマンドライン環境を強化するというものだ。そもそもcmd.exeは、MS-DOS由来であり、Powershellにしても、スクリプト言語としての機能強化はあったものの、いわゆる「シェル」としては、使い勝手がいまいちの部分がある。
たとえば、bashなどUnix/Linux系のシェルが持っている「ジョブコントロール」や前回ちょっと紹介したtmuxをはじめとする端末仮想化管理ツールなどにより、コマンドライン環境を強化するというわけだ。WSLのbashからWindowsのデスクトッププログラムを起動できるWin32相互運用性の存在やWSLからの起動が高速であることを考えると、コマンドラインの環境やvi、emacsといったUnix/Linux由来のキャラクタベースのツールにLinux並の環境(なにせLinuxそのもの)を与えるという点で多くのメリットがあるように思える。また、Linuxのバイナリがそのまま起動するわけで、Linux用の開発ツールのWindowsへの移植自体も不要となる。
もっとも、これを「手抜き」と考えるか、「進歩」と考えるのは、人それぞれだとは思うが。
この連載の記事
-
第459回
PC
WSL 2.4.4ではtar形式でのディストリビューションが配布でき、企業での利用が容易になってきた -
第458回
PC
Windows上でhostsファイルを活用する -
第457回
PC
IPv6アドレスは先頭を見ればどんな種類かわかる -
第456回
PC
あらためてIPv6基本のキ -
第455回
PC
Windowsで現在どのネットワークアダプタがインターネット接続に使われているかを調べる方法 -
第454回
PC
Windows 11 24H2では「デバイスの暗号化」の条件が変わり、より多くのPCでドライブが暗号化される -
第453回
PC
Windows 11 24H2の配布開始後もすぐにはやってこない Windows UpdateとSafeguard Holds -
第452回
PC
Windows 11 Ver.24H2が登場 Copilot+ PCとそうでないPCで実質Windowsが2つに分かれる -
第451回
PC
新しいWindowsサンドボックスではコマンドラインからの制御が可能に -
第450回
PC
ユニコードで文字数を数える方法 -
第449回
PC
WSLはプレビュー版でGUIでの設定が加わった! リリース2.3.xの新機能を見る - この連載の一覧へ