トップ 検索 一覧 ヘルプ RSS ログイン

コマンドプロンプトのエスケープ仕様の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
(2010/10/23:追記)[cmd.exe のコマンドラインの仕様を解析してみた - 永遠に未完成|http://d.hatena.ne.jp/thinca/20100210/1265813598]が詳しいのでそちらを見たほうが早いかもしれません。

!!!コマンドプロンプトのエスケープ仕様

コマンドプロンプトで、コマンドに空白を含む文字列を渡したい場合、二重引用符「"」で囲む必要があることは多くの方が知っていると思う。

しかし、その他のエスケープシーケンスはどうなっているのだろうか。Windows XP SP3のマシンでヘルプ内を探してみたが、それらしい記述が見つからない。どうしてそんな基本的な仕様を明確に書いていないのだろうか…。

等と思っていたところ、殆ど偶然に、[MSDNにその記述|http://msdn.microsoft.com/ja-jp/library/78f4aasd(VS.80).aspx]を発見したのでメモしておく。

{{bq
引数は、空白 (スペースまたはタブ) で区切ります。

キャレット (^) は、エスケープ文字やデリミタとしては認識されません。カレットは、オペレーティング システムのコマンド ライン パーサーによって完全に処理されてからプログラムの argv 配列に渡されます。

二重引用符で囲まれた文字列 ("string") は、空白を含む場合でも、単一の引数と見なされます。二重引用符で囲んだ文字列を引数に埋め込むこともできます。

円記号を前に付けた二重引用符 (\") は、リテラル二重引用符文字 (") として解釈されます。

二重引用符の直前にある円記号以外は、円記号 (\) として解釈されます。

二重引用符の直前に円記号が偶数個 (0 個は含まない) あると、円記号のペアごとに 1 個の円記号が argv 配列に格納されます。この場合、二重引用符は文字列のデリミタとして解釈されます。

二重引用符の直前に円記号が奇数個 (3 個以上) あると、円記号のペアごとに 1 個の円記号が argv 配列に格納されます。最後の円記号によって二重引用符がエスケープ シーケンスになるため、二重引用符文字 (") がそのまま argv に格納されます。
}}

わかりづらい書き方だが、要は以下の通り。
*キャレット「^」は何の特別な意味もない。
*空白を含む引数はエスケープ文字としての二重引用符「"」で囲うこと。
*二重引用符「"」自体を引数(データ)に含めたい場合は「\」を前に付けること。
*二重引用符の前にデータとして「\」を付けたい場合、「\」を2回以上つけるが…
**この場合、2つの「\\」が1つの「\」に置き換わるように動作する。
**例えば「\\"」は2つの「\」が1つの「\」に置き換えられ、残りの「"」はエスケープ文字になる。
**例えば「\\\"」は2つの「\」が1つの「\」に置き換えられ、残りの「\"」がデータとしての「"」になる。
**つまり、最後の「"」はその前の「\」が奇数個ではデータになり、偶数個ではエスケープ文字になる。
*上記以外の「\」は単なるデータの「\」になる。

というわけで、「"」をデータとして含めたいときはその前にエスケープ文字「\」を置き、その前にさらにデータとしての「\」を起きたい場合は2個ずつセットで置く(合計で奇数個の「\」が続く)ようにすればよい。

まぁ、「"」の前にどうしても「\」を置きたいケースはそれほど多くない気がするので、あまり気にする必要はなさそう。

!!その他の特殊記号

実際にはコマンドプロンプトで特別な意味を持つ記号は他にも、<,>,|,(,),&,%がある。これらのうち、%以外は二重引用符「"」で囲むことでエスケープできたが、%だけは回避できなかった。例えば
 echo %PATH%
とすれば環境変数PATHの内容が表示されるが、これを環境変数に展開せず、「%PATH%」と表示させる方法が分からない。
 echo %%PATH%%
としても環境変数PATHの内容の前後に%が付くだけだ。もちろん
 echo "%%PATH%%"
等としても効果はない。

そこで、気づくのが冒頭のMSDNの内容。今までキャレット「^」なんて気にしたこと無かったが、これがわざわざ書いてあるのには意味があるはずだ。というわけで
 echo ^%PATH^%
としたところ、望み通りの「%PATH%」という表示がされた!

おうい、マイクロソフトさん、「^」はエスケープ文字として働いているようですが…?それとも冒頭の表記は、C#コンパイラとの関わりでしか有効ではないのだろうか。

その後、「キャレット」でヘルプを検索し直してみると、echoコマンドの項目に<,>,|の文字がエスケープできることが書いてある。今度はechoコマンドのみでの対応なのかが気になったため、テストしてみた。やり方は、「%PATH%.txt」という名前のファイルの内容をtypeコマンドで表示してみるだけのものだ。普通に
 type %PATH%.txt
とすると、やはり動作がおかしい。そこで
 type ^%PATH^%.txt
と書くと、見事ファイルの内容が表示された。

どうやら「^」でのエスケープはechoコマンドに限った話ではない模様。

!!結論

基本的には「"」で囲む。「"」自体をデータに含める場合は「\」を前置。「"」の前にデータとして「\」を置きたい場合はエスケープ用の「\」1つに加えて、「\」を2個ずつセットで置く。%をエスケープしたい場合は「^」を使用する。「^」は他にも使えるかも。