前回に続いて、Windows 10のAnniversery Update(RS1)から搭載されたWindows Subsystem for Linux(WSL)について詳しく紹介する。今回はWSLの中からシステムを見ていこう。
Windows Subsystem for Linux内から
Windows側のファイルにアクセスする
前回、WSLで動作するUbuntu Linuxのルートファイルシステムは、「%userprofile%\appdata\local\lxss\」にあると紹介したが、これをWSL側から見たのが下の図だ。
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に戻ってくる。
このようにすると、あたかもLinuxのコマンドをWindowsのコマンドと同じように利用することができる。WSLの起動は短時間ででき、仮想環境を起動するときのような負荷はかからない。このため、ソフトウェア開発などで、gccなどLinux側の開発系コマンドを利用してコンパイルするといった作業が簡単にできる。そうなっていると、bash.exeとカレントディレクトリが同じになっているほうが便利だ。ただし、WSL側のコマンドでWindows側のファイルをフルパスで指定する場合には、/mnt/cなどからなるWSL側ファイルシステムに翻訳してパラメーター指定する必要がある。
また、Linux側では大文字小文字が区別される点に注意する必要がある。たとえば、DevFsでウィンドウズフォルダ(C:\Windows)をアクセスする場合「/mnt/c/Windows」はアクセスが可能だが「/mnt/c/windows」ではアクセスができない。
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ディレクトリなど)は本来あるべき情報がない場合がある。
同様に/procは、起動中のプロセス(Process)の情報にアクセスするためのProcファイルシステムになっている。/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 カーネルが行っている。
さて、次回は、WSLのLinuxを使いやすく設定する設定などについて考えてみることにする。
この連載の記事
-
第460回
PC
Windowsでsftpを使う -
第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
ユニコードで文字数を数える方法 - この連載の一覧へ