• Escape from Command Line

コマンドラインを司るシェルでは、いくつかの記号文字に特殊な意味を持たせている。bashやPowerShellそしてcmd.exeでは、“|”にコマンドの出力を次段のコマンドに入力するための「パイプ」を表す記号として使い、“>”や“<”を「リダイレクト」文字として扱う。bashではこれをメタ文字と呼び、PowerShellでは、演算子(パイプ演算子、リダイレクト演算子。ただし出力のみ)といい、cmd.exeでは特殊文字という。

しかし、場合によっては、これらの記号文字に特別な意味を持たせたくない場合がある。こうした場合、シェルは、その意味を打ち消す方法を提供している。これをまとめたのが(表01)だ。

  • ■表01

bashやPowerShellでは、引用符で囲む方法を「Quoting(クオート)」という。その他に後続の文字の意味を打ち消す「エスケープ文字」や、オプション文字によるオプション指定を終了させる「–」などの方法がある。

二重引用符(解釈付き引用符)と一重引用符(解釈なし引用符)の違いは、囲まれた文字列内で特殊文字を使った置換やエスケープ処理の有無である。

PowerShellは、先行成功事例であるUnixのシェルを手本としており一重引用符、二重引用符があるが、エスケープ文字には逆クオートを使う。一重引用符では、その中が評価されないという点は同じだが、2つ連続する一重引用符「”」を使うことで、一重引用符内に一重引用符を入れることができる。

PowerShellにも、bashと同じ“–”があり、PowerShellでは「パラメーター終了トークン」と呼んでいる。もう1つ「解析停止トークン」と呼ばれる“–%”がある。これは、このトークン以降をPowerShellでは解釈しないことを示す。外部コマンドの引数などがPowerShellによって解釈されることを防ぐ。たとえば、cmd.exe /cを呼び出すような場合


cmd.exe /c --% echo "dir|x"

とすることで、PowerShellが「”dir|x”」を解釈してコマンドとして扱ってしまうことを防ぐ。

cmd.exeは、MS-DOS時代から段階的に改良されてきたため、複雑な挙動を持つ。まず、二重引用符は、ファイルパス中のスペースなどの特殊文字を含めるための表記である。なので引数部分まで含めてしまうとエラーになる。具体的には、


cmd.exe /c "c:\Program Files\PowerShell\7\pwsh.exe" -noprofile

のようにファイルパス部分のみを囲う。これを


cmd.exe /c "c:\Program Files\PowerShell\7\pwsh.exe -noprofile"

のようにしてしまうとエラーになる。

現在のWindowsでは、コマンドラインにcmd.exe、PowerShell、bashをパイプ記号で混在させることができる。このとき、注意するのは、起動環境に従ったエスケープ方法が必要になる点。 たとえば、PowerShellからbashコマンドを呼び出すとき


Get-ChildItem | wsl.exe -- grep 'test' `| sort -k 5

としてbash側で実行させるパイプ文字にPowerShellのエスケープ文字を付ける。こうした方法をまとめたのが(表02)だ。最初のコマンドとパイプ文字は、起動環境で解釈されるが、2つ目のコマンドとパイプ文字は別環境に解釈させる必要がある。そのためには、コマンドを引用符で括る、あるいはエスケープ文字を使う必要がある。

  • ■表02

今回のタイトルネタは、1981年の映画「Escape from New York」(監督John Carpenter。邦題ニューヨーク1997)である。荒廃した社会と放置された悪人集団、そして必ずしも正義ではない主人公、このあと、アニメやマンガ、ゲームなどでよく見ることになるコンセプトの作品。