Linuxは、すでに普及しているプラットフォームの1つ。Webサーバーなどにも使われるが、普通のPCに入れてメインマシンとする人もいる。また、AndroidやChromeOSはLinuxカーネルで作られている。Linuxはカーネルとさまざまな周辺ソフトウェアを組み合わせた「ディストリビューション」で利用するのが普通だが、このディストリビューションは、UNIXを手本としたものが大半で、コマンド名やデーモン起動、ディレクトリ構造などをUNIXから受け継いでおり、Linux/UNIX環境といった呼び方をされるときもある。

  • 窓辺の小石

かつて、UNIXとX Window SystemなどのGUI環境を組み合わせたUNIXワークステーション(WSと略すこともあった)が広く使われていた時代もあった。1980年台から90年台にかけてのことだ。当時、将来のコンピューターハードウェアは、PCなのかWSなのかといった議論もあった。また、AT互換機で動作するUNIXもあり、次世代OSは、Windowsなのか、UNIXなのかといった議論もあった。

そういうUNIXに連なるLinuxは、PCで動かすことが多いものの、対応しているアーキテクチャーは幅広い。オープンソースであるため、まったく新規のCPUアーキテクチャにも対応できることもあり、たとえば、RISC-Vなどでもすでに動作している。この先も新しいプラットフォームが登場したとき最初に動くオペレーティングシステムはLinuxになるだろう。

こうしたLinuxだが、以前は、Windowsとのデュアルブートや仮想マシンでの利用、あるいは別マシンを用意しての利用が普通だったが、MicrosoftがWindows Subsystem for Linux(以下WSLと略す)を出して以来、Windowsとの距離はぐっと縮まった。そして、昨年は、よりLinuxとの互換性が高いWSL Ver.2(以下WSL2と略す)も登場している。

もし、WSやUNIX、あるいはLinuxの利用経験があったら、WSL2をすぐにでも導入したほうがよい。というのは、WSLは、Linuxでありながら、Windowsのコマンドが実行可能な「ハイブリッド」な環境であり、Windowsのコマンドが出力するデータを、UNIX/Linuxのコマンドで処理することが可能だからだ。過去には、Windows内でUNIXに似た環境を実現しようとするCygwinや、Microsoft自身によるPOSIX環境などもあったが、WSLは、もっとWindowsに近くかつLinuxそのものだ。というよりも、LinuxがWindowsに「半分埋まっている」という感じだ。

Windows Preview版では、WSLでKVM(Kernel Virtual Machine)が動作しエミュレーター環境のQEMUが動く。NVIDIAのWSL専用ドライバーを使えばCUDAを動作させ、AIのトレーニング環境を構築することも可能だ。さらにWaylandベースのLinuxのGUIアプリケーション対応も予定されている。WSLは、本物のLinuxと遜色ないものに変化しつつある。

WSLを使う

まだWSLをインストールしてない人のために最短のインストール方法を解説しておく。また、少し前にWSLは入れたのだけれど、そのあと使わなくなったという人は、Linuxアプリケーションの互換性が高まったWSL2を入れみてほしい(最初のWSLはLinuxカーネルはエミュレーションだった)。WSL2は、本物のLinuxカーネルを使い、たとえばコンテナ環境のDockerなども動くようになった。WSL2は、Windows10のVer.1903以降であれば、Homeエディションでも動作する。

WSLをインストールするには、管理者権限でコマンドプロンプト(CMD.EXE)を起動する。以下の説明はPowerShellではそのまま動かないので適宜読み替えてほしい。手順は(リスト01)以下のようなものだ(実行例を写真02に示す)。このあと、Microsoftストアから自分の使いたいLinuxディストリビューションを探してインストールする。インストールしたらスタートメニューに作られたアイコンを選択して、ディストリビューションのインストールを行う。

(リスト01)

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all
(コマンド終了後にWindowsは再起動を要求してくる)
再起動後に再び管理者権限でコマンドプロンプトを開き以下のコマンドを実行する
cd %Userprofile%\downloads
curl.exe -O https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
start wsl_update_x64.msi
wsl.exe --set-default-version 2
  • 写真02

WSLを最初に搭載されたときにインストールしてみたが、今は使ってない人にも、WSL2を試してみることをおすすめしたい。インストールは、前記のリスト01#%MTH%#の最初のコマンドを飛ばして2つめから最後までを実行し、すでにインストールしてあるWSLディストリビューション(ここではUbuntu-18.04を想定)を以下のコマンドを使ってWSL2で動作するように変更する。

wsl.exe --set-version Ubuntu-18.04 2

これで、WLS2を使う準備ができた。

WSLでWin32コマンドも起動可能

UNIXはGUI操作も可能だが、本来、コマンドライン(シェル)で使うもので、基本的な操作はすべてコマンドラインから可能だ。Linuxもこれを引き継いでいる。Windowsもコマンドラインで利用可能ではある。PowerShellは、意外に「いい線行っている」が、コマンド名が冗長、言語とコマンドラインインタープリターとしてのバランスが少し悪くて、言語側に傾きすぎている部分がある。ご存じの方には言うまでもないことだが、UNIX/Linuxのシェルは、長い間コマンドラインインタープリターとして揉まれ、かつ言語としても揉まれてきた関係で、シェルに必要な簡潔な入力とスクリプト言語としての側面の微妙なバランスを達成している。

たとえば、PowerShellでは、スペースを含むパスのコマンドを実行するときには、単にパスをシングルクオートで囲んでしまうと、「文字列」と解釈されてしまってプログラムが起動しない。プログラムを実行させるためには、シングルクオートの前に「&」を付ける必要がある(写真03)。ここは言語として厳密さを重視しすぎていると筆者は思っている。これに対してbashでは、スペースを含むパスにある実行ファイルでも単にシングルクオートで括るだけでよい(もっともLinuxではスペースを含むパス名は利用可能だが、ほとんど利用されていない)。なお、PowerShellの名誉のために言っておくと、パスの補完機能を使うとスペースを含むパスの場合、自動的にシングルクオートで括られて先頭に&が付けられる。また、コマンドの引数なら文字列のままでも問題ない(コマンドが引数を解釈するため)。しかし、クリップボード経由で貼り付けを行う場合などにちょっと面倒くさい。

  • 写真03: PowerShellは残念ながら、言語仕様に忠実すぎて、コマンドラインインタープリターとしては、いささか使いにくいところがある

さて、このWSLでは、Windows側(WSL側と対比する場合には、Win32側と呼ぶ)の実行ファイルを起動することもできる。Win32側と違って拡張子の省略ができない(実行ファイルの拡張子の省略はMS-DOSからのルール)。WSLとWin32では、ファイルシステムが違うが、お互いの流儀のパス表記で相互にアクセスが可能だ(図01)。標準では、WSL側にWin32側のPath環境変数などが渡るため、衝突がなければ、Win32側のコマンド、たとえばcmd.exeなどはそのまま起動可能だ。

  • 図01: Win32とWSL側では、お互いのファイルの参照方法に違いがある。このため、Win32とWSLコマンドを混在させる場合、パスがどこを刺しているのかにちょっとした注意が必要だ。とはいえどちらも自分の側にあるファイルは通常の方法でアクセスが可能

Win32側のコマンドラインでは、wsl.exeコマンドを使ってWSL側のプログラムの起動ができる。たとえば、フォルダー内のファイル/フォルダーの数を数えるには、「dir/B | wsl -- wc」とWin32のコマンド(dirは、cmd.exeの組み込みコマンド)とWSL側のコマンド(wc。Word Count。標準入力で受け取った文字列の文字数、ワード数、行数を数える)を組み合わせることができる。一見、この方法が正当そうだが、そうではない。Windowsでコマンドラインを便利に使うには、WSL内からWin32のコマンド(もちろんGUIコマンドだって実行できる)を呼び出すほうがいいのだ。たとえば、Windowsのサービスを制御するsc.exeによるサービス一覧から特定のキーワード、svcとserviceが含まれたサービス名を探すには、

sc.exe query | grep -i -E 'SERVICE_NAME:.*(svc|service)'

とgrepコマンドで正規表現が使える(写真04)。Win32側には正規表現の文字列検索コマンドはないので、同じくWSL側のegrepを使うとすると

sc.exe query | wsl.exe -- grep -i -E "SERVICE_NAME:.*(svc|service)"

としなければならない。"wsl.exe --"は、後続のコマンドをWSL側で実行させるもの。Linuxコマンドの前にこれを置く必要がある。Win32側は、シングルクオートではパイプ記号などの特殊記号が有効になってしまうため、正規表現によってはダブルクオートで括らねばならないなどの面倒な判断が必要になる。なので、コマンドプロンプトの代わりにWSLのコンソールを開いて、そこからWin32のコマンドとLinuxのコマンドを使ったほうがスッキリする。

  • 写真04: Win32側からWSL側のコマンドを使うよりも、WSL側でWin32側のコマンドを呼び出すほうが簡単。また、grepコマンドが持つカラー出力(一致部分に色を付ける)も有効になる

なにも普段コマンドラインを使わない人にまで、WSLを勧めるつもりはないが、Windowsでコマンドラインを日常的に使うようなら、その本流ともいえるLinuxのコマンドラインを使ってみるのはどうだろう? そもそも現在のWindowsに付属するcmd.exeの内部コマンドや書式は、MS-DOSのcoomand.comからのもの。MS-DOSは、Ver.2.0でUNIXを手本にパイプやリダイレクション、階層化フォルダーを取り込んだ。Ver.1.0との互換性のため、すでにオプション文字でスラッシュを使っていたcommand.comは、パス区切りが逆スラッシュ(日本語環境では\)になってしまった。これを変更してしまうと、オプション指定を含むユーザーのバッチファイルがすべて動かなくなるからだ。少し「不肖の息子」ともいえるWindowsのコマンドラインではなく、ある意味「本物」のコマンドラインに慣れるのもいいかもしれない。

bashの祖先となったBourne ShellがUNIX V7として導入されたのは1979年。シェルが利用されてきた期間は、Windowsよりも長い(Windows Ver.1.0は1985年)。筆者には、Windowsやそのコマンドラインが将来どうなるかはわからないが、少なくともLinuxのコマンドラインに関してはLinuxが生き続ける限り残る。いまから乗り換えても決して遅くはないだろう。