このページの本文へ

Windows Info 第113回

Windows Subsystem for Linuxの起動とバックグラウンドタスク

2018年01月21日 10時00分更新

文● 塩田紳二 編集● ASCII編集部

  • この記事をはてなブックマークに追加
  • 本文印刷

 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への移植自体も不要となる。

 もっとも、これを「手抜き」と考えるか、「進歩」と考えるのは、人それぞれだとは思うが。

カテゴリートップへ

この連載の記事

注目ニュース

ASCII倶楽部

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン