web-dev-qa-db-ja.com

バックスラッシュを使用してcmd.exeの文字をエスケープする(例としてrunasコマンド)

キャレットは文書化されたエスケープ文字であることがわかります。

ただし、二重引用符文字の場合、^は機能せず、\を使用する必要があることを示す例があります。

C:\>runas /user:Administrator "cmd /k dir \"%userprofile%\""

それはなぜですか、どこに文書化されていますか?

7
barlop

RUNAS /?の例の1つは、その構文を示しています。キャレットはCMD.EXEのエスケープ文字ですが、Windowsでは個々のプログラムが独自のエスケープ文字とグロビングを自由に実装できます。

Cmdでは、\notエスケープ"を行います。ここに簡単な証明と説明があります:

  1. echo "" & echo 1を実行します。 (&はcmdの特殊文字です。left & rightleftを実行してからrightを実行することを意味します。)echo ""echo 1は正常に実行されました。

  2. 次に、echo " & 1234を実行します。出力が" & 1234であることがわかります。これは、最初の"が閉じられていないため、特殊文字&を含め、その後のすべてが文字列として解釈されるためです。

  3. echo "\" & 1234を実行します。

    • \が次の"をエスケープする場合、開始"は閉じられず、文字& 1234は文字列の一部として解釈されます。

    • \が次の"のエスケープに失敗した場合、thatが次の"によって文字列を閉じ、& 1234notを文字列の一部として解釈します。

    出力では、& 1234は文字列の一部として解釈されていません。 これは、\"をエスケープできなかったことを証明します。

では、引数を渡すために引用符内で"をエスケープするにはどうすればよいでしょうか。 ^は引用符の外でも機能しますが(echo ^" & echo 1で簡単に証明されます)、引用符内の引用符をエスケープしません。

実際、echo """&echo 1のような単純なものを機能させるにはどうすればよいでしょうか。

^ char? ...いいえ、echo "^"" & echo 1"^""ではなく"""を出力します。

" char自体はどうですか? ...いいえ、echo """" & echo 1""""ではなく"""を出力します。

実際は引数を渡すための引用符内で"をエスケープするものはありませんです。あなたはこれを2、3年間抱いて、解決策にたどり着くことはできません。これは、cmdスクリプトに固有の制限の一部にすぎません。

しかし、良いニュースは、あなたがそうする必要がある状況に遭遇する可能性が最も高い決してないということです。確かに、echo """&echo 1を動作させる方法はありませんが、これはそれほど問題にはなりません。

たとえば、runasを考えます。 runas knewこれを行う方法がなく、それを回避するために内部調整を行っているため、引用符内で"をエスケープする必要はありません。 runasは独自の解析ルール(runas /flag "anything even including quotes")を発明し、cmd引数を通常の方法で解釈しません。これらの特別な構文の公式ドキュメントはかなりまばらです(または存在しません)。 /?helpは別として、ほとんどが試行錯誤です。

15
Pacerier

\記号は、インタープリターに次の記号をidentifierではなくcharacterとして解釈させます。

あなたはそれをコードでもたくさん見ます:

"Hello \"World\""

これは解釈済みとして

Hello "World"

あなたの例では、cmdに引数を渡すために、 ""で囲む必要があります。ただし、cmdへの引数には "が含まれているため(これによりエンクロージャーが終了します)、\によって追加されます。" "がなかった場合、/k dir \"%userprofile%\"runasではなくcmdへの引数として解釈されます。

それらが%userprofile%を囲んでいる理由は、これが環境変数であり、スペースを含む可能性のあるテキストに置き換えられるためです(上記と同じ理由で)cmdへの引数が正しくなくなります。

4
Default