torutkのブログ

ソフトウェア・エンジニアのブログ

[Windows]PowerShellコマンド環境で引っかかったこと

以前から、2,3年に1回程度の頻度でWindows OS上でのコマンドライン環境(CLI)にCygwinではなくPowerShellを使おうとして、その度に挫折してCygwinに戻ってしまうことを繰り返しています。

今週末(5月21日)に開催される日本Javaユーザーグループ主催のカンファレンス(JJUG CCC 2016 Spring)で発表する機会を得て、そのデモでPowerShellを使おうとして準備をしていましたが、いろいろ引っかかってしまい、コマンドプロンプトに変更してしまいました(発表で使用するノートPCは、Cygwinを入れないようにしているので)。

空白を含むパスのコマンドの実行

まず、文字列のクォートなしにJavaのコマンドを絶対パスで指定して実行しようとしたら、これは予想通りエラーとなりました。

PS R:\> C:\Program Files\Java\jdk1.8.0\bin\javapackager.exe
C:\Program : 用語 'C:\Program' は、コマンドレット、関数、スクリプト ファイル、または
操作可能なプログラムの名前として認識されません。名前が正しく記述されていることを確認
し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してください。
発生場所 行:1 文字:1
+ C:\Program Files\Java\jdk1.8.0\bin\javapackager.exe
+ ~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Program:String) [], CommandNotFou
   ndException
    + FullyQualifiedErrorId : CommandNotFoundException

PS R:\>

そこで、ダブルクォートで囲ってみたところ、

PS R:\> "C:\Program Files\Java\jdk1.8.0\bin\javapackager.exe"
C:\Program Files\Java\jdk1.8.0\bin\javapackager.exe
PS R:\>

と文字列がそのまま評価されて表示されるだけとなってしまいました。

調べたところ、文字列をコマンドとして実行するには、先頭に&を付けるということでした。

PS R:\> & "C:\Program Files\Java\jdk1.8.0\bin\javapackager.exe"
使用方法: javapackager -command [-options]

このコマンドは次のいずれかです。

コマンドの引数でハイフンとピリオドを含む文字列を指定したら引数が分割されてしまった

javaのコマンドオプションでシステムプロパティを指定したところ、エラーとなってしまいました。

PS R:\> java -Dfile.encoding=UTF-8 -version
エラー: メイン・クラス.encoding=UTF-8が見つからなかったかロードできませんでした
PS R:\>

PowerShellでは、ハイフン(「-」)で始まり途中にピリオド(「.」)を含む文字列があると、ピリオドの前で分割する振る舞いをするようです。

この問題についてQ&Aは見かけましたが、仕様なのかバグなのかは不明です。

http://stackoverflow.com/questions/28704867/why-does-powershell-split-arguments-containing-hyphens-and-periods

PowerShellのコマンドでも発生します。

PS R:\> echo alfa bravo.1 -charlie.2
alfa
bravo.1
-charlie
.2
PS R:\>

回避策としては、ハイフンで始まりピリオドを含む文字列をクォートします。

PS R:\> java "-Dfile.encoding=UTF-8" -version