• 記事
  • Windows Subsystem for Linuxガイド 第2回 コマンド編

Windows Subsystem for Linuxガイド 第2回 コマンド編

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

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

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

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)に示す。

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

Windows Subsystem for Linuxガイド 第2回 コマンド編

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

標準出力の文字コード

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

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

コードページとはコンソールでメッセージなどを表示するとき使われる文字コード(文字エンコード)を指定するもの。日本語環境では、コードページは原則“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)。

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

パッケージマネージャー

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

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

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

sudo apt updateapt search キーワード

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

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

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