Windows 10のLinux互換環境WSLからコマンドプロンプトのプログラムを呼び出す(バージョン1803対応版)Tech TIPS

さまざまなコマンドなどを組み合わせて自動処理したり、Windows系のツールが出力するメッセージを処理したりするなら、Linuxのツールの方が便利なことが多い。WSLからWindows系のコマンドを呼び出したり、組み合わせたりして使う方法を解説する。

» 2018年05月31日 05時00分 公開
[打越浩幸デジタルアドバンテージ]
「Tech TIPS」のインデックス

連載目次

対象OS:Windows 10バージョン1709以降(64bit版のみ)


WSLからWindowsのコマンドプロンプトのプログラムを呼び出して処理する

 Windows 10に「WSL(Windows Subsystem for Linux)」をインストールすると、Linux向けのプログラム(バイナリファイル)をそのまま実行することができる。WSLのインストール方法については、TIPS「Windows 10でLinuxプログラムを利用可能にするWSL(Windows Subsystem for Linux)をインストールする」を参照していただきたい。

 またTIPS「Windows 10のコマンドプロンプトからWSL上のLinuxコマンドを呼び出す」では、コマンドプロンプトからWSLのコマンドを呼び出して処理する方法を取り上げている。ここでは、先頭に「wsl 〜」と付けるだけで、WSL側のコマンドが起動できることを紹介した。

 これとは逆に、WSL側からコマンドプロンプト側のプログラムやツールなどを呼び出すことも可能だ。本TIPSではその方法を紹介する。

WSLからコマンドプロンプトのプログラムを呼び出すには?

 WSL側からWindows上のプログラムを直接呼び出す方法は簡単である。単に、起動したいプログラムのパス名を拡張子まで含めて指定すればよい。

 例えばタスク一覧を表示するコマンド(実行ファイルは「C:\Windows\System32\tasklist.exe」)を実行したいのならば、「tasklist.exe」と指定する。コマンドプロンプト上で実行する場合は、拡張子の「.exe」を省略できるが、WSLから呼び出す場合は必ず拡張子まで指定する必要がある。

 これ以外にも幾つか注意点があるのでまとめておく。

  • コマンドプロンプト側のプログラムを起動するには、拡張子まで含めて指定する
  • PATH環境変数に登録されていない場所にあるコマンドの場合は、フルパスで表記する
  • コマンドプロンプト(cmd.exe)の内部コマンド(独立した実行プログラムファイルとして用意されていないコマンド)やスクリプトファイルなどを実行したい場合は、「cmd.exe /c dir」のように、先頭に「cmd.exe /c 〜」を付けて実行する
  • バッチファイルの実行は、利用できるコマンドと文字コードに注意する
  • コマンドプロンプト側のパス名を指定する場合は、特殊文字を「\」でエスケープするか、引用符で囲む
  • Windows OS側コマンドはコードページ=65001(UTF-8)の環境で実行されるので、日本語文字列などが含まれる場合は注意する

 以下、それぞれについて補足しておこう。

起動するコマンドは拡張子まで含めて指定

 コマンドプロンプト側では、実行ファイルの拡張子は省略してもプログラムを起動できるが、WSL側から起動する場合は.exeや.batなどの拡張子も含めて全て指定する必要がある(ただしバッチでは実行できないコマンドが多くあるので注意。詳細は後述の「バッチファイルを実行したい場合は、利用できるコマンドに注意」参照)。CUIのツールだけでなく、GUIのプログラムでも起動できる。

Windowsコマンドの起動 Windowsコマンドの起動
Windows側のコマンドを起動するには、拡張子まで全て指定する。

PATH環境変数に登録されていないプログラムはフルパスで指定

 コマンドプロンプト側で設定されているPATH環境変数の値は、WSL側にも引き継がれている。そのため、PATH環境変数で示される場所にあるコマンドならば、ファイル名と拡張子を指定するだけで起動できる。PATHの設定についてはTIPS「Windows 10でPath環境変数を設定/編集する」を参照していただきたい。

 だがPATHが通っていない場所にあるコマンドを実行したい場合は、WSL上のフルパス名で指定する必要がある。

PATH上にないWindowsプログラムの起動 PATH上にないWindowsプログラムの起動
PATHが通っていない場所にあるプログラムを起動するには、WSLのフルパス表記で指定すればよい。

内部コマンドなどは「cmd.exe /c 〜」で実行

 コマンドプロンプトの内部コマンドや、内部コマンドを含むバッチファイルなどはWSL側から直接実行することができない。それらを実行したい場合は、cmd.exeに/cオプションを付けて「cmd.exe /c 」のようにして、コマンドプロンプト側で実行させる。

内部コマンドの起動 内部コマンドの起動
コマンドプロンプト(cmd.exe)が持つ内部コマンドを起動するには、前に「cmd.exe /c 」を付けるとよい。

バッチファイルを実行したい場合は、利用できるコマンドに注意

 バッチファイルでは、例えば「@echo off」や「setlocal」「echo 〜」「if 〜」といった内部コマンドをよく使うが、これらが含まれるバッチファイルをWSLから起動しようとすると、全てエラーとなってしまう(もしくはLinuxのシェルで解釈されてしまう)。前述の通り、これらの内部コマンドには、「cmd /c 」と書き直さないと、Windowsのコマンドとして認識されないためだ。

 しかし、いちいち直すのは面倒である。そこで、WSLからバッチファイルを呼び出したい場合は、「cmd.exe /c mybatch」のように、バッチファイルそのものを「cmd.exe /c 」で実行するとよい。

バッチファイルの起動 バッチファイルの起動
バッチファイルをWSLから直接起動しようとしても、エラーになることが多い。「cmd /c 」を使って、コマンドプロンプトに実行させるとよい。

Windowsのパスに含まれる特殊文字に注意

 WSLとWindows OSではパス名の表記方法が異なるので、WSL(Linux)のパス指定をそのままWindows OSのコマンドプロンプト側へ渡してもエラーになる。事前にWindows OSのパス表記に変更する必要があるが、空白文字や(パス区切りの)バックスラッシュ(\)が含まれている場合は全体を引用符で囲む。

パスに含まれる特殊文字に注意 パスに含まれる特殊文字に注意
Windowsのファイルシステムでは空白文字やバックスラッシュなどの特殊な文字が使われていることが多い。WSL表記からWindows表示へ変換するとともに、全体を引用符で囲んで引数とする。

 WSLのパス形式とWindowsのパス形式を相互に変換するには、WSL用のwslpathコマンドが利用できる。wslpathコマンドについてはTIPS「Windows 10のコマンドプロンプトからWSL上のLinuxコマンドを呼び出す」を参照のこと。

 なお、WSLから呼び出されたコマンドは、カレントドライブは「C:」、カレントフォルダは「\Windows\System32」という状態で起動する。そのため、ファイル名などをパラメータとして渡す場合は、常にフルパス名で渡すのがよい。

Windowsコマンドの起動パス Windowsコマンドの起動パス
WSLから呼び出されたコマンドは、「C:\Windows\System32」がカレントフォルダに設定された状態で実行されるようである。パス名などを引数として渡す場合は、カレントフォルダの場所がどこであっても問題ないように、フルパスにすることが望ましい。

Windows側コマンドはコードページ=65001(UTF-8)の環境で実行される

 TIPS「Windows 10のコマンドプロンプトからWSL上のLinuxコマンドを呼び出す」でも述べているように、WSL環境では、文字コードは「UTF-8(コードページ=65001)」としてプログラムが実行されている。

 しかし日本語Windows OSのコマンドプロンプトでは、デフォルトの文字コードはShift_JIS(コードページ=932)となっている。なので、コマンドの実行結果に日本語文字が含まれる場合は、注意が必要である(次の記事も参照)。コマンド側の出力がShift_JISなら、WSL側で受け取った後、UTF-8に変換するなどの対策を行う必要があるだろう。Windows OSに標準で付属するコマンドは、コードページ設定に応じて適切な文字コードにして出力するものが多いが(日本語Shift_JISメッセージと英語メッセージを切り替えるだけだが)、そうでないコマンドも多数ある(このあたりは、実際にやってみて適宜対応するしかない)。

文字コードに注意 文字コードに注意
日本語WindowsではShift_JISを使っているが、WSL側から呼び出された場合はUTF-8になっている。なので、テキストデータを受け渡したり、バッチ中で日本語を使ったりする場合は、UTF-8にしたり、文字コード変換をしたりすること。
※nkfは漢字コードを変換するツール(こちらのTIPSを参照)。Ubuntuなら、「apt update」「apt intall nkf」の手順でインストールできる。

 なおコマンドプロンプト側で起動するバッチ中で、日本語文字列をShift_JISで記述していると(例えば「echo 日本語です」を実行するバッチファイルをShift_JISで記述しておくと)、WSLから呼び出した場合に文字化けしてしまう(UTF-8環境で実行されるため)。どうしてもWSL側から呼び出したければ、バッチファイルをUTF-8環境向けに作り直したり、日本語メッセージを使わないバッチにしたりする、などの対策が必要である。

「Tech TIPS」のインデックス

Tech TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

AI for エンジニアリング
「サプライチェーン攻撃」対策
1P情シスのための脆弱性管理/対策の現実解
OSSのサプライチェーン管理、取るべきアクションとは
Microsoft & Windows最前線2024
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。