Windows Subsystem for Linuxのファイルシステムを知る

アスキー 10月16日(日)10時00分配信

 前回に続いて、Windows 10のAnniversery Update(RS1)から搭載されたWindows Subsystem for Linux(WSL)について詳しく紹介する。今回はWSLの中からシステムを見ていこう。

Windows Subsystem for Linux内から
Windows側のファイルにアクセスする

 前回、WSLで動作するUbuntu Linuxのルートファイルシステムは、「%userprofile%\appdata\local\lxss\」にあると紹介したが、これをWSL側から見たのが下の図だ。

11
WSLから見えるファイルシステムは、各ユーザーのフォルダにあるAppData/Local/lxssにあり、ここにあるrootfsがWSLのルートファイルシステムに相当する。ただし、一部のディレクトリは分離されている。また、Windows全体のファイルシステムは、WSL側からは/mnt/以下に「マウント」されている

 Linuxでは、通常、rootfsと呼ばれる何もないファイルシステムにHDD内のパーティションや仮想ファイルシステムなどをマウントしていく。Windowsと違って「ドライブ」や「ドライブ文字」といった概念はなく、記憶デバイスなどはrootfsにつながるディレクトリに「マウント」して利用する。なお、標準のパス区切りには、「/」(スラッシュ)を使う。

 Windowsも実はAPIのパラメーターとしてはパス区切りにスラッシュ文字を使うことが可能だ。MS-DOSの元になったQDOSでコマンドのオプション文字として「/」を使っていたため、MS-DOS 2.0で階層ディレクトリを導入したとき、オプションとパラメータの区別がつかなくなるため、パス区切りを逆スラッシュ「\」(ASCIIコードの0x5C)にした。オプション文字のほうを修正すると、付属コマンドのほとんどを改修する必要があるからだ。

 また、バッチファイルがスラッシュをオプション文字として記述していたため、変更すると、バッチファイルがすべて動作しなくなってしまうという互換性の問題を引き起こすというのも理由だった。つまり、逆スラッシュを使わねばならないというのは、コマンドラインでパスを指定するときの問題だったわけだ。それ以降、Windowsのコマンドラインやエクスプローラーの表示は、すべて逆スラッシュでパスを区切るようになった。

 実際には、マイクロソフトはシステムのオプション「SWITCHCHAR」を組み込み、オプション文字にスラッシュ以外に指定できるようにして、APIのレベルでは、パスの区切りを逆スラッシュ、スラッシュのどちらでも受け付けるようにしている。しかし、SWITCHCARオプションはサードパーティのアプリに対して互換性の問題を発生させたため、利用は制限されて「隠し機能」とされたのだ。

 APIのレベルでパス区切りをスラッシュ、逆スラッシュどちらでも受け付けるという機能は以来ずっと健在である。たとえば、Windows Explorerのアドレス欄(パス欄)に「C:\temp\folder」の代わりに「C:/temp/folder」と入れてもちゃんとフォルダを移動してくれる。ただし、パスの表示は常に逆スラッシュになる。

 さて、WSLに話を戻そう。WSL内からWindows側のファイルへアクセスするには、「/mnt」以下にあるドライブ文字別のディレクトリを使う。このときWindows側の「C:\」は、WSLでは「/mnt/C」となる。これは、WSLに組み込まれた「DeviceFs」と呼ばれるファイルシステムだ。

 このDeviceFsでは、WSL側からみるとLinuxのファイルシステムだが、すべてのファイルシステム機能はサポートされておらず、主な機能のみが利用可能で、WindowsのファイルシステムへのアクセスがLinux側のソフトウェアから行えるようになっている。

 このDevFsにより、WSL側からは、Windows側の任意の位置にあるファイルをアクセスできる。わざわざVolFSがあるユーザーディレクトリ以下にファイルを置く必要はなく、Windows側のエディタによる編集などが簡単にできる。

 ただし、Linuxでは、一般的にテスキトファイルの行末記号として「LF」(0x0A)を使い、Windowsでは、CRLF(0x0D 0x0A)を使うのが普通だ。このため、Windows付属のメモ帳では、Linux側のファイルがぜんぶつながって見えてしまう。WindowsとWSLでテキストファイルを共有する場合、行末記号の設定可能なエディタを使う必要がある。

 また、bash.exeコマンドで、WSLを起動したとき、WSL側のカレントディレクトリは、bash.exeのものが引き継がれる。たとえば、コマンドプロンプトウィンドウのカレントフォルダーが「C:\Windows\System32」だったとき、bash.exeを起動すると、WSL側のカレントディレクトリは、「/mnt/c/Windows/System32」になる。

 Linux環境を起動したとき、bash.exe側のカレントディレクトリが引き継がれることにちょっと違和感を感じるLinuxユーザーも少なくないだろう。通常のLinuxやUnix環境では、ログインした直後は、ユーザーのホームディレクトリがカレントディレクトリになるためだ。

 bash.exe側のカレントディレクトリが引き継がれる理由は、bash.exeがLinuxのコマンドを実行して終了するという使い方ができるからだ。実際には、bash.exeを実行すると、Linux側のログイン手続きはなく、すぐに/bin/bashが起動してLinuxのプロンプトに切り替わる(ただし、bashのログインスクリプトなどはちゃんと実行されている)。cmd.exeからbash.exeを起動するときに"-c”オプションに続けてLinuxのコマンドを指定すると、コマンドを実行後、bash.exeの実行が終了してcmd.exeに戻ってくる。

11
bash.exeは、/bin/bashと同じオプションを受け付けることが可能。このためコマンドを実行させる“-c”(小文字のc)と実行コマンド(写真中ダブルクオートの中)を指定すれば、WSL側でコマンドを実行してCMD.EXEに戻ってくる

 このようにすると、あたかもLinuxのコマンドをWindowsのコマンドと同じように利用することができる。WSLの起動は短時間ででき、仮想環境を起動するときのような負荷はかからない。このため、ソフトウェア開発などで、gccなどLinux側の開発系コマンドを利用してコンパイルするといった作業が簡単にできる。そうなっていると、bash.exeとカレントディレクトリが同じになっているほうが便利だ。ただし、WSL側のコマンドでWindows側のファイルをフルパスで指定する場合には、/mnt/cなどからなるWSL側ファイルシステムに翻訳してパラメーター指定する必要がある。

 また、Linux側では大文字小文字が区別される点に注意する必要がある。たとえば、DevFsでウィンドウズフォルダ(C:\Windows)をアクセスする場合「/mnt/c/Windows」はアクセスが可能だが「/mnt/c/windows」ではアクセスができない。

11
Linuxでは、大文字小文字が区別されるため、/mnt/c以下のファイルアクセスでは大文字小文字に注意すること。「C:/Windows」はWが大文字として登録されている

 Windowsでは通常、大文字小文字は区別されないが、作成時の大文字小文字の指定は保存される。このため、WSL側では、その大文字小文字を区別する必要がある。フォルダを作成する場合「mkdir Temp」と「mkdir temp」は、Windows側では区別がされないが、Linux側からみると違いが出てきてしまうわけだ。なので、VolFs側にWindows側からフォルダなどを作成する場合には、なるべく小文字のみを使うなど注意する必要がある。

 WindowsのNTFSなどのファイルシステムでは、実際には、大文字小文字を区別している。しかし、これをWindows Subsystemから使う場合には、大文字小文字を区別しないでアクセスできるようになっている。これはもともとWindows NTがPosixサブシステム(Unix準拠のAPIを持つシステム)を持ち、そのために大文字小文字を区別する必要があったからだ。

Linuxのファイルシステムに含まれる特殊なディレクトリ

 Linuxのファイルシステムには、/sysや/porc、/devといった特殊なディレクトリがある。これらは疑似ファイルシステムと呼ばれるものだ。疑似ファイルシステムは、さまざまな情報をファイルのようにアクセスできる仕組み。/sysは、sysfsと呼ばれカーネル内の情報にアクセスする場合に利用する。たとえば、

/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq

というファイルを開くと、CPUコアの最大動作クロック周波数をテキストとして読み出すことができる。ただし、WSLでは、Linuxカーネルそのものが動作しているわけではないので、/sysディレクトリ以下の一部(たとえばfsディレクトリなど)は本来あるべき情報がない場合がある。

11
/sysは、カーネルなどが持つさまざまなシステム情報<3677>をファイルシステムとして表現したもの。この画面では、CPUの最大動作クロック周波数がファイル(cpuinfo_max_freq)にテキストとして表現されており、catコマンドでこれを表示させている

 同様に/procは、起動中のプロセス(Process)の情報にアクセスするためのProcファイルシステムになっている。/procディレクトリ以下にプロセス番号に相当するディレクトリが作られ、その下に個々のプロセスに対する情報がある。

11
/procは、起動中のプロセスに関する情報を仮想ファイルシステムとして表現したもの。プロセス番号に対応するディレクトリがあるほか、動作に関連する情報を得ることもできる

 /devは、Unixが当初からもっているデバイスファイルシステムで、カーネルが扱うデバイスを仮想的なファイルシステムとして表現したもの。/devファイルシステムは、コマンドなどから直接デバイスを操作する場合などに利用する。

 bash.exeを起動すると、WSL内では、initプロセスと/bin/bashプロセスの2つが起動する。initプロセスは、Linuxでカーネルが起動したあと、ユーザープロセスとしてシステムの起動に必要な処理を行うプロセスを起動するプログラム。いわゆるオペレーティングシステムの起動処理を行い、通常は、バックグラウンドなどで動作するプログラム(Linux/Unix系ではデーモンと呼ぶ)を起動するなどの処理を行う。

 しかし、WSLは、最低限のLinux環境になっており、デーモン(バックグラウンドで動作するソフトウェア。Windowsのサービスに相当)は一切起動されない。唯一起動されるプログラムが/bin/bash(bash.exeではないことに注意)で、これがいわゆるLinuxのシェル(bash)になる。

 実は、このinitも/bin/bashも、Windowsのプロセスとして管理されている。タスクマネージャには、initもbashもちゃんとプロセスとして表示される。つまり、WSLのプロセスは、コードはLinuxのバイナリだが、プロセスとしては、Windowsのカーネル側で正式なプロセスとして扱われている。メモリ管理やスケジューリングもWindows カーネルが行っている。

11
WSLで起動されるLinuxのプログラムinitや/bin/bashもWindowsのプロセスとして管理されているため、タスクマネージャやTasklistコマンドで表示させることができる。ただし、Windows Subsystemのプロセスではないためにプロパティ表示などはできない

 さて、次回は、WSLのLinuxを使いやすく設定する設定などについて考えてみることにする。

アスキー
もっと見る もっと見る

【あわせて読む】

    最終更新: 10月16日(日)10時00分

    【関連ニュース】

    【コメント】

    • ※コメントは個人の見解であり、記事提供社と関係はありません。

    【あなたにおススメ】