Windows 10のコマンドプロンプトからWSL上のLinuxコマンドを呼び出す(バージョン1803対応版):Tech TIPS
テキスト処理を行う際などでは、Windows OSよりもLinuxの方が、ツールが豊富で機能も多く、便利なことが多い。普段Windows OSをメインにしているユーザーでも、必要なときだけコマンドプロンプトからWSLのツールを呼び出せれば助かるだろう。その方法を紹介する。
対象OS:Windows 10バージョン1709以降(64bit版のみ)
コマンドプロンプトからWSLのプログラムを呼び出す
Windows 10に「WSL(Windows Subsystem for Linux)」をインストールすると、Linux向けのプログラム(バイナリファイル)をそのまま実行することができる。
例えばテキストデータの処理では、awkやsed、tr、cut、sort、uniq、〜grep、head、tail、……など、非常に多くの「定番」と呼ばれるツールが利用されるが、Windows OSではsortぐらいしか用意されていなかった。また文字コードがUTF-8になると、標準のWindows OSのツールだけではほぼどうしようもない。これまでは、ほとんどの場合、こうしたツール類をWindows OS向けに誰かがリリースしてくれるのを待つしかなかった。しかしWSLを利用すれば、これらのツールがそのまま利用できるので、入手に悩む必要はない。
具体的なWSLのインストール方法については次の記事を参照していただきたい。
上記のTIPSでは、UbuntuやSUSE、DebianなどのLinuxのパッケージをインストール後、シェルを起動して利用する方法を紹介している。
だがWSL環境では、従来のWindows OSのコマンドプロンプトからLinuxのプログラムを直接呼び出すことも可能だ。この機能を利用すると、Windows OS向けのプログラムとLinux向けのプログラム(特にテキスト処理フィルタのツールなど)をパイプ機能で連結して連続処理させることができる。
Windows OSで利用できるツールは、元々はUNIXにあったプログラムを参考にしているとはいえ、種類も機能も大幅に不足している。UNIXなどのコマンドをWindows OSに移植したツール類もあるが(SUAやMSYS、Git for Windowsなど。TIPS「【総まとめ】Windowsコマンドプロンプトの入門から使いこなしまで」の「●コマンドプロンプトだけでは機能が不足する場合は?」項参照)、インストールやバージョンアップなどの操作が少々面倒である。
それと比較すると、WSL上のプログラムを直接呼び出すのは非常に簡単だし、バージョンアップなども容易だ(通常のLinuxパッケージの更新方法でよい)。本TIPSでは、コマンドプロンプト(cmd.exe)からWSL上のプログラムを呼び出す方法を紹介する。
WSL上のプログラムを呼び出すには、先頭に「WSL 〜」を付けるだけ
Linuxのプログラムを使うには、最初にWSLをインストールしておく必要がある。上記のTIPSの手順に従って、どのディストリビューションでもよいのでWSLのLinuxをインストールし、一度起動して初期設定を済ませておく。
コマンドプロンプトからLinuxのプログラムを呼び出すためには、Linuxコマンドの前に「wsl 〜」というコマンド名を追加するだけだ。各ディストリビューションのアイコンをクリックしてWSL環境(bash)を起動する必要はない。例えばWSL上の「ls -lsa」コマンドを実行したければ、コマンドプロンプト上では「wsl ls -lsa」と入力する。
「wsl」は、実際には「C:\Windows\System32\wsl.exe」というプログラムを呼び出す指示である。これを実行すると、WSL上にインストールされているLinuxディストリビューションのシェル(通常は/bin/bash。Tech Basics「bash」参照)を呼び出して、引数に指定されたコマンドを起動する。その結果はコマンドプロンプトに返され、画面に表示される。またパイプで連結すれば、Windows OSのコマンドとWSLのコマンドを任意に組み合わせて処理できる。
dirコマンドの出力をwcコマンドでカウントしている例
wc(word count)はテキストファイルの行数や単語数、文字数を数える(有名な)LinuxのコマンドであるがWindows OSには用意されていない。「wsl wc」とすればWSL上のwcを呼び出せる。
※[注]「dir /s」の結果に日本語文字が含まれる場合は、WSLへ渡す前に「nkf -w」でUTF-8へ変換するなどの処理を行うこと。
使いたいコマンドがLinux上にない場合は、ディストリビューションごとの標準的な手順で追加しておけばよい。例えばUbuntuなら「apt install 〜」でパッケージをインストールできる(次のTIPS参照)。
複数のディストリビューションをインストールしている場合は?
WSL環境では、一人のユーザーが同時に複数のLinuxディストリビューションをインストールして使い分けることができるが、単にwslと入力すると、「デフォルトの」ディストリビューションのbashが呼び出される。
複数インストールしている場合は、「wslconfig」コマンドで一覧を取得したり、デフォルトディストリビューションを指定したりできる。「wslconfig /list」でインストールされているディストリビューションの一覧とデフォルト設定が表示され、「wslconfig /setdefault 〜」でデフォルトを変更できる。
日本語文字が含まれる場合は文字コード変換が必要
WSLでは文字コードとして「UTF-8」を利用しているが、日本語Windows OSのコマンドプロンプトでは「Shift_JIS」コードがデフォルトとなっている。そのため、日本語文字が含まれるようなテキストをパイプでWSL側に渡したり、逆にWSL側から受け取ったりする場合は注意が必要だ。適切な文字変換プログラムを途中で適用しないと、文字化けした状態で処理されてしまう(パイプやリダイレクトの処理において、自動的に文字コードが変換されることは、ない)。
文字コード変換をするツールにはiconv(Linuxに標準でインストールされている)やnkfなどがあるので、好みのものを使えばよいだろう。なおこれらのツールは、Windows OS向けのバイナリも用意しておくと、いろいろな場面で利用できて便利である。特にnkfは文字コードの自動判別をしてくれるので、何か文字化けしているようなら、とりあえず最後にnkfに通して(Shift_JISに変換して)みる、という使い方を筆者はよく行っている。
- Linux基本コマンドTips「【 iconv 】コマンド――文字コードを変換する」(Linux & OSSフォーラム)
- TIPS「nkfツールで文字コードを変換する(Windows編)」
WSLにおける文字コードの扱いや、具体的にどのように文字コード変換するべきかについては、以下の記事を参照していただきたい。
- Windows 10 Latest「Windows 10に搭載されたLinuxサブシステムにおける、Windowsプログラムとの連携や日本語処理機能を検証する」
なお、wsl側のコマンドに渡す引数に日本語文字列が含まれている場合は、自動的にUTF-8に変換されているようなので、この部分を手動で変換しておく必要はないようだ(例:「…… | wsl grep 日本語 | ……」のような使い方は可能ということ)。
WindowsとWSLにおけるファイルパス名の変換
Windows OSとWSL(上のLinux環境)では、ファイルのパス名の扱いが異なる。例えばWindows OSの「C:\〜」はWSL上では「/mnt/c/〜」に対応する。
なので、例えばローカルの「C:\Users\user01\Doc\file1.txt」というパス名をWSLのプログラムに渡したい場合は、「/mnt/c/Users/user01/Doc/file1.txt」のようにしなければならない。
この変換は少し面倒なので、Windows 10のバージョン1803以降のWSLには、この変換をサポートするために「wslpath」というコマンドが用意されている。これはWSL上でのみ動作するコマンドである(Windows OS向けの.exeはない)。Windows側から渡されたパスは、このコマンドを使ってLinux側でパスを変換してから使っていただきたい。
コマンド | 意味 |
---|---|
wslpath <Windowsパス> | WSL向けのパスに変換する |
wslpath -a <Windowsパス> | WSL向けの絶対パスに変換する |
wslpath -w <WSLパス> | WSLからWindowsパスに戻す(パス区切りは「\」) |
wslpath -m <WSLパス> | WSLからWindowsパスに戻す(パス区切りは「/」) |
WindowsパスとWSLパスを変換するwslpathコマンド |
実行すると次のようになる。
wslpathによるWindowsとWSLのパスの変換例
wslpathはLinux上で動作するツール。Windows OSとやりとりするパスをWSL向けに変換したり、逆変換したりできる。パス区切りが「/」でも、Windows OSでは引用符で囲むとパス名として利用できる(ことが多い)。
このようなツールでいちいちパス名を変換するのが面倒なら、WSLにはパイプ機能でデータを渡すだけにすれば簡単だ。例えば次のようにする。これならばいちいちinputfile.txtやoutputfile.txtのパスを変換する必要はない(Windows向けのバイナリのnkfの場合、「nkf -w」でUTF-8に変換し、引数なしの「nkf」でShift_JISに戻せる)。
mywincmd1 < inputfile.txt | nkf -w | wsl mywslcmd2 | nkf > outputfile.txt
Windowsドライブのマウント
WSLのコマンドを呼び出した場合、Windows OS側にあるドライブのうち、リムーバブルドライブ(USBメモリなど)やネットワークドライブは、WSL側では自動的にマウントされていない(リムーバブルではない、固定的なNTFSやFATドライブは「/mnt/<ドライブ名>」パス経由でアクセスできる)。それらのドライブにWSL側からもアクセスしたい場合は、自動マウントさせておくとよいだろう。具体的な方法については以下のTIPSを参照していただきたい。
以上、簡単にWSL上のプログラムを呼び出す方法を紹介した。今までは、UNIXやLinuxにあったあのツールが欲しいので、同等の機能のコマンドを探すという面倒なことを行っていたが(本TIPSでもそのようなツールを幾度となく紹介してきた)、WSLが利用できるなら、すぐに利用できるので便利である(ただし、文字コードがShift_JISではなくてUTF-8になるので、文字化けなどに注意する必要があるが)。
本TIPSでは、コマンドプロンプトからWSLを呼び出す方法を紹介したが、逆にWSL側からWindows側のプログラム(.EXEファイル)を呼び出すこともできる。これについては、TIPS「Windows 10のLinux互換環境WSLからコマンドプロンプトのプログラムを呼び出す(バージョン1803対応版)」を参照のこと。
Copyright© Digital Advantage Corp. All Rights Reserved.