ここでは、WSL最大の特徴であるコマンド混在実行について解説する。ただし、Linuxやbashの基本的な使い方は解説しないので書籍やインターネットの解説サイトなどを参照してほしい。

WSLには、複数のLinuxディストリビューションが利用可能だが、ディストリビューションごとにコマンドに細かな違いがあるため、ここでは特定のディストリビューションを例に解説を進めることにする。具体的には、Ubuntu 20.04 LTSをベースにコマンドの解説を行う。

・Ubuntu 20.04 LTS
https://www.microsoft.com/ja-jp/p/ubuntu-2004-lts/9n6svws3rx71?activetab=pivot:overviewtab

なお、現時点では、UbuntuとUbuntu 20.04 LTSは同じものである。

・Ubuntu
https://www.microsoft.com/ja-jp/p/ubuntu/9nblggh4msv6?activetab=pivot:overviewtab

インストールなどに関しては、前回の記事を参考にされたい。

・Windows Subsystem for Linuxガイド 基本編
https://news.mynavi.jp/article/20211203-2211548/

また、この記事で使う、基本的な用語に関しては、簡単に表にまとめて記事末に掲載してある。そのほか、Linuxのコマンドの基本的なことに関しては、Linuxのmanコマンドで確認できる。たとえば、grepコマンドについて知りたければ“man grep”とすることで詳細な情報が得られる。

コンソールプログラムを導入

Windows 10まで標準で使われてきたコンソールウィンドウは、文字コード(文字エンコード)をコードページで切り替えているため、世界的な標準になりつつあるUTF-8で文字列を扱うプログラムの実行環境としては問題がある。

WSLは、Windows標準のコンソールでも動作するようになっているが、標準コンソールではUTF-8でのテキスト入力が正しく行えないなどの問題があり、WSLを使うのであれば、Windows Terminalあるいは、サードパーティのコンソールプログラム(端末エミュレーターとも)を利用することを強くお勧めする。この記事では、原則、コマンドの出力例などは、Windows Terminalを利用している。

Windows Terminalは、Microsoftがオープンソースで開発を進める、コンソールホストプログラムの後継版だ。Windows 11からは、標準コンソールとして利用することも可能になった。Windows Terminalは、Microsoftストアから入手できる。

・Microsoft Store Windows Terminal
https://www.microsoft.com/ja-jp/p/windows-terminal/9n0dx20hk701?activetab=pivot:overviewtab

Windows Terminalに関しては、以下の記事を参考にされたい。

・Windows Terminalのキーボードカスタマイズ 導入編
https://news.mynavi.jp/article/20211025-2168960/

WSLとLinux

WSL最大の特徴は、コマンドライン上でWin32コマンドとLinuxのコマンドを混在できる点にある。Windowsでは、Hyper-Vやサードパーティの仮想マシン環境(VMWareやVBOXなど)を使えば、Linuxを動かすことはできる。しかし、これは、あくまでもWindowsとは完全に分離された仮想マシンの中のもので、cmd.exeなどから仮想マシン内のコマンドを起動することはできない。

WSLでは、cmd.exeやPowerShellといったWin32のコマンドライン(シェル)から、wsl.exeコマンドを使って、Linux/bashのコマンドを1つの行にまとめて記述できる。逆に、wsl.exeコマンドで起動したLinux/bash環境の中でもWin32コマンドの起動が行える。

wsl.exeコマンドの起動関連のコマンドラインとオプションを(表01)に示す。

  • ■表01

Win32側でのwsl.exeによるWSL側コマンドの実行は、以下のようになる


ftype | wsl -- egrep -i "^[^=]*\.(jpeg|jpg)"

これはcmd.exe内での実行である(写真01)。ftype(cmd.exeの内部コマンド)の出力をLinuxのコマンドegrep(正規表現検索)に渡して処理するものだ。

  • 写真01: WSLは、仮想マシンでのLinuxとは違い、コマンドライン上でWin32コマンドとWSLコマンドを混在させて実行できる。また、WSL内でもWin32コマンドを実行できる。このとき、どちらもコマンド出力をそのまま相手に渡し、文字コードの変換などはおこなわれない

WSLの中でWin32コマンドを起動して


cmd.exe /c ftype | egrep -i '^[^=]*\.(jpeg|jpg)'

と同じことができる。WSLでWin32コマンドを実行する機能を「Win32相互運用性」(Win32 Interop)という。

この場合、Win32側のコマンドの実行ファイル名を指定する必要があるため、拡張子の.exeを必ず付ける。また、cmd.exeの内部コマンド(上記のftypeコマンドなど)を実行する場合には、cmd.exeの“/c”オプションの引数として指定する。上記の例は、どちらもパイプ記号“|”の左側はWin32コマンド、右側がWSLコマンドである。こうしたパイプによるWin32/WSL混在コマンドの記述パターンを(表02)に示す。

  • ■表02

注意するのは、Win32側でパイプ記号またはバーチカルバー文字“|”を、WSL側のパイプ記号やバーチカルバー文字して使う場合だ。cmd.exeやPowerShellでは、パイプ記号を認識して処理している。このため、WSL側でパイプとして認識させたい場合には、パイプ記号の前にエスケープ文字(cmd.exeは“^”、PowerShellは"`")を置いて、cmd.exeやPowerShellがパイプ記号として解釈しないようにする。

ファイルパスをコマンドの引数に使う場合、パスを解釈するのは、それぞれのコマンドであり、その流儀に従う必要がある。Win32側からWSL側コマンドを実行する場合に引数にパスを指定するならLinux形式とする。WSL側でWin32コマンドを起動する場合でパスを引数とする場合には、Windowsの通常形式で指定を行う。ただし、bashでは、Win32側パス区切り文字の“\”がエスケープ文字になるため、シングルクオートで括って指定する。

標準出力の文字コード

Win32、WSLのコマンドをパイプで混在させたとき、基本的には、文字コード(文字エンコード)は自動的には変換されないため、必要に応じてどちらかで変換を行う。

Win32側がcmd.exeの場合、日本語環境では、Win32コマンド出力の文字コード(文字エンコード)に注意が必要だ。原則Win32コマンドの出力は、コードページ指定に従うが、コマンドによっては、コードページと異なる文字コードが出力されることがある。たとえば、Windowsのサービスのリストを出力するsc.exeでは、日本語名がついたサービスは、コードページ設定にかかわらず、シフトJISコードで出力される(写真02)。

  • 写真02: Win32コマンドの中にはシステムから得たテキストをそのまま出力するものがある。日本語版Windowsでは、このため、コードページを切り替えてもシフトJISテキストが出力されることがある。WSLでWin32コマンドを処理する場合、このような状況になることを想定しておく必要がある

コードページとはコンソールでメッセージなどを表示するとき使われる文字コード(文字エンコード)を指定するもの。日本語環境では、コードページは原則“Shift JIS”(コードページ番号932)が使われ、米国英語環境では、437が使われる。コードページの確認や変更は、cmd.exeの内部コマンドchcpで確認できる。

WSL側からWin32コマンドを実行するとき、Windowsの「システムロケール」設定(コントロールパネル ⇒ 地域 ⇒ 管理タブ ⇒ Unicode対応ではないプログラムの言語)に従ってコードページが指定される。日本語版Windowsでは、標準でここに「日本語(日本)」が設定され、WSLからWin32コマンドを実行するとき、コードページに932(日本語シフトJIS)が指定された状態になる。ただし、「ベータ:ワールドワイド言語サポートでUnicode UTF-8を使用」のチェックボックスをオンにしている場合、WSLから起動するWin32コマンドでは、コードページに65001(UTF-8)が指定された環境が使われる。

なお、コマンド出力をコンソールで表示する場合、Win32コマンドではシフトJISが(コードページが932の場合)、WSLコマンドではUTF-8が仮定されている。このため、コマンドの出力を直接コンソールに表示させると文字化けしないが、逆に仮定と反する文字コードで出力が行われると文字化けする(写真03)。

  • 写真03: コンソール出力に関しては、仮定された文字コードを変換して表示が行われる。Win32コマンドの出力はシフトJISであると仮定されているため、UTF-8を出力すると化けてしまうが、逆にWSLコマンドの出力はUTF-8と仮定されているため、シフトJISを出力すると化けてしまう。ただし、文字コード変換が起こるのはコンソールに出力したときのみで、コマンド間のテキスト引き渡しでは変換がおこなわれない

WSLコマンドのコンソール出力を見ると、正しく表示されるので出力がシフトJISに変換されているように見えるが、コマンド間のテキスト受け渡しでは変換がおこなわれない点に注意が必要だ。

パッケージマネージャー

WSLを使う上で避けて通れないのが、Linuxディストリビューションのパッケージ管理だ。パッケージとは、プログラムやライブラリ、設定ファイルなどを、ソフトウェアごとにまとめたもの。現在のLinuxではインターネットに設置されたリポジトリと呼ばれるパッケージの集積サイトを利用してプログラムの検索やインストールができる。ここでは、とりあえず、簡単にパッケージマネージャーコマンドについて解説し、詳細な解説に関しては別の機会としたい。

パッケージは多数あり、ユーザーは検索機能でこれを探し、必要なものをインストールする。このとき、パッケージマネージャーは、パッケージに記述された情報に従って、必要なライブラリなども自動的にインストールしてくれる。

(表03)は、Ubuntuで使われているdpkg系のパッケージマネージャーのaptコマンドの一覧である。aptコマンドには、サブコマンドがあり、これと引数を組み合わせてパッケージ管理を行う。たとえば、「キーワード」を手がかりにパッケージを探すには、


sudo apt update
apt search キーワード

とする。「キーワード」には、正規表現による検索パターンも指定できる。なおいくつかのaptコマンドは、管理者権限が必要になる。このときには、aptコマンドの前にsudoコマンドを前置し、aptコマンドを管理者権限で実行させる必要がある。

  • ■表03

発見したパッケージに関する情報を見るには、“apt show パッケージ名”を使い、パッケージをインストールするには、“apt install パッケージ名”コマンドを使う。なお、インストールされないコマンドを実行しようとすると、エラーメッセージにパッケージ名などが示されることがある(写真04)。

  • 写真04: 存在しないコマンドを実行しようとしたとき、もし、同名のコマンドを持つパッケージが存在している場合、Ubuntu-20.04では、エラーメッセージでインストールコマンドを提案してくれる

コマンドラインでのWin32、WSLコマンドの混在は、WSLの一番のポイントだ。もちろん、無理にコマンドを混在させる必要はなく、それぞれを個別に使ってもいいのだが、bashでもcmd.exeと同じようにWin32コマンドが利用でき、cmd.exeでもgrepなどのLinuxの便利なコマンドが利用できるという点が仮想環境で実行するLinuxとは違うということは意識したほうがいいだろう。なお、最後に本記事でのキーワードの解説を(表04)に掲げておく。

  • ■表04