バッチスクリプトでの二重引用符のエスケープ


91

バッチファイルのパラメーターのすべての二重引用符をエスケープされた二重引用符で置き換えるにはどうすればよいですか?これは私の現在のバッチファイルで、文字列内のコマンドラインパラメータをすべて展開しています。

@echo off
call bash --verbose -c "g++-linux-4.1 %*"

次に、その文字列を使用してCygwinのbashを呼び出し、Linuxクロスコンパイラーを実行します。残念ながら、次のようなパラメーターをバッチファイルに渡しています。

"launch-linux-g++.bat" -ftemplate-depth-128 -O3 -finline-functions 
-Wno-inline -Wall  -DNDEBUG   -c 
-o "C:\Users\Me\Documents\Testing\SparseLib\bin\Win32\LinuxRelease\hello.o" 
"c:\Users\Me\Documents\Testing\SparseLib\SparseLib\hello.cpp"

渡された最初のパスを囲む最初の引用符が、GCCに渡される文字列を途中で終了させ、残りのパラメーターをbashに直接渡す(これは、見事に失敗します)。

パラメータを単一の文字列に連結して、引用符をエスケープして正常に機能するかどうかを想像しますが、これを行う方法を決定するのが困難です。誰か知っている?

回答:


103

バッチスクリプトのエスケープ文字は^です。ただし、二重引用符で囲まれた文字列の場合は、引用符を二重にします。

"string with an embedded "" character"

5
引用符を2倍にしてもうまくいきませんでしたが、^はチャンピオンのように働きました。
davenpcj 2013年

25
^引用符囲まれていない文字列のみのエスケープ文字です。二重引用符で囲まれた文字列では、リテラルとして扱われます。Unix(POSIXのような)シェルとは異なり、二重引用符で囲まれた文字列内の二重引用符のcmd.exe標準化されたシェル処理を提供せず、呼び出されるプログラムに解釈が委ねられます(次のコメントに続きます)。
mklement0 2015

9
(前のコメントから続く)実際には、ほとんどの実行可能ファイル/スクリプトインタープリターは、"文字を期待するというCの規則を適用します。\"二重引用符で囲まれた文字列の内部としてエスケープされます(少なくともC / C ++、Python、Perl、Rubyに適用されます)。対照的に、""少数の場合にのみ認識されます:バッチファイルに渡されるパラメーターで"" 埋め込まれた二重引用符として認識されますが、で囲んでいる二重引用符を削除した後でも、対応するパラメーターでそのまま保持され%<n>ます。Python は、の代替として、礼儀正しく認識します。%~<n>""\"
mklement0

89

eplawless自身の答えは彼の特定の問題を簡単かつ効果的に解決します:"引数リスト全体のすべてのインスタンスをで置き換えます\"。これは、Bashが二重引用符で囲まれた文字列内の二重引用符を表すために必要な方法です。

Windowsコマンドラインインタープリターを使用して、二重引用符で囲まれた文字列内の二重引用符をエスケープする方法cmd.exeの質問に一般的に答えるために(コマンドラインで-多くの場合、誤って「DOSプロンプト」と呼ばれることがあるか、またはバッチファイルで):PowerShellの概要については、下を参照してください。

tl; dr

  • 文字列を(他の)に渡すときに使用する必要""あります、バッチファイル、あなたは可能使用""して作成されたアプリケーションと、マイクロソフトのC / C ++ / NETコンパイラ。受け入れる\"Windows上で)、 PythonとのNode.jsを含み

    • 例: foo.bat "We had 3"" of rain."

    • 以下は、バッチファイルにのみ適用されます。

      • ""cmd.exe二重引用符で囲まれた文字列全体を単一の引数として扱うコマンドインタープリタ()を取得する唯一の方法です。

      • ただし、残念なことに、囲まれた二重引用符が(通常どおり)保持されるだけでなく、二重にエスケープされた引用符も保持されるため、目的の文字列を取得することは2段階のプロセスです。例えば、二重引用符で囲まれた文字列を第一引数として渡されると仮定し、%1

      • set "str=%~1"囲んでいる二重引用符を削除します。set "str=%str:""="%"次に、二重の二重引用符を単一の二重引用符に変換します。
        値の不要な解釈を防ぐために、割り当て部分を囲む二重引用符を使用してください。

  • \"必要です -唯一のオプションとして-他の多くのプログラム(たとえば、Ruby、Perl、さらにはMicrosoft独自のWindows PowerShell(!))でも必要ですが、その使用は安全ではありません

    • \"多くの実行可能ファイルとインタープリター(Windows PowerShellを含む)に外部から文字列渡すときに必要なものです。または、Microsoftのコンパイラーの ""場合は、代替としてサポート -最終的に、引数リストを解析するのはターゲットプログラム次第です。
      • 例: foo.exe "We had 3\" of rain."
    • しかし、の使用\"不要な、任意のコマンドの実行および/またはINPUT / OUTPUTのリダイレクトでできる結果
      • 次の文字がこのリスクを示しています。 & | < >
      • たとえば、次の場合、verコマンドが意図せずに実行されます。説明と回避策の次の箇条書きについては、以下を参照してください。
        • foo.exe "3\" of snow" "& ver."
    • 以下のためのWindows PowerShell\""および"^""堅牢であるが、限られた選択肢(以下「PowerShellののCLIを...呼び出し」を参照してください)。
  • を使用する必要がある場合\"安全なアプローチ3つしかありません、これは非常に面倒です。TSの助けのためのヒント

    • バッチファイルで(場合によっては選択的な)遅延変数展開を使用して、リテラル\"変数に格納し、構文"..."を使用してその変数を文字列内で参照できます!var!。TSの役立つ回答を参照してください。

      • 上記のアプローチは、面倒ではありますが、系統的に適用でき、堅牢に機能するという利点があります、あらゆる入力に。
    • リテラル文字列(変数を含まない文字列)を使用した場合のみ、同様に系統的なアプローチが得られます:カテゴリ別^ cmd.exe " & | < > - すべてのメタ文字をエスケープます%
      foo.exe ^"3\^" of snow^" ^"^& ver.^"

    • それ以外の場合は、終了区切り文字として誤って解釈されたために、文字列のどの部分が引用符なしであるcmd.exeと見なされるかを認識することに基づいて、文字列を作成する\"必要があります

      • リテラルシェルのメタ文字を含む部分: ^それらを-escape。上記の例を使用する&と、^エスケープ。
        foo.exe "3\" of snow" "^& ver."

      • 部分で持つ%...%スタイルの変数参照:それは確実cmd.exeにその一部とみなし"..."、文字列をし、変数の値が自分自身をないということは、アンバランス引用符に埋め込まれている- でも、常に可能ではありません

背景情報については、以下をお読みください。


バックグラウンド

注:これは私自身の実験に基づいています。私が間違っている場合は私に知らせてください。

Unixライクなシステムの BashなどのPOSIXライクなシェルは、引数をターゲットプログラムに個別に渡す前に引数リスト(文字列)をトークン化します。他の拡張の中でも、それらは引数リストを個別の単語に分割(単語分割)し、引用文字を結果の単語(引用の削除)。ターゲットプログラムが渡され、アレイ個々の引数をして、構文の引用符を削除します

対照的に、Windowsコマンドインタープリターは明らかに引数リストをトークン化せず、引用符を含むすべての引数を含む単一の文字列を渡すだけです。-ターゲットプログラムへ。
ただし、単一の文字列がターゲットプログラムに渡される前にいくつかの前処理が行われます:^エスケープ文字。二重引用符で囲まれた文字列の外側は削除され(次の文字をエスケープします)、変数参照(たとえば%USERNAME%)が補間されます最初にます。

したがって、Unixとは異なり、引数文字列を解析し、引用符を削除して個々の引数に分解するのは、解析するのがターゲットプログラムの責任です。このように、異なるプログラムが仮想的に異なる脱出方法を必要とすることができますし、された単一のエスケープ機構もありませんが保証するすべてのプログラムで動作するようには - https://stackoverflow.com/a/4094897/45375は、Windowsのコマンドラインでアナーキーに優れたバックグラウンドが含まれています解析。

\"上記のように、実際には非常に一般的ですが、安全ではありません

それcmd.exe自体はエスケープ\"れた二重引用符として認識されないため、コマンドラインで後のトークンを引用符なしとして誤って解釈し、それらをコマンド入出力リダイレクトとして解釈する可能性があります一言で言えば、次のいずれかの文字が続く場合、問題は、表面開口またはアンバランスを。例えば:
\"& | < >

foo.exe "3\" of snow" "& ver."

cmd.exeは、\"通常の二重引用符として誤って解釈した結果として、次のトークンを表示します。

  • "3\"
  • of
  • snow" "
  • 残り: & ver.

引用符で囲まれていcmd.exeないと考えるので、それ& ver.は(コマンドシーケンス演算子)として解釈され、その後に実行するコマンドの名前が続きます(- は無視されます。バージョン情報を報告します)。 全体的な効果は次のとおりです。&ver..vercmd.exe

  • 最初に、foo.exe最初の3つのトークンのみで呼び出されます。
  • その後、コマンドverが実行されます。

偶発的なコマンドが害を及ぼさない場合でも、すべての引数がコマンドに渡されるわけではないため、コマンド全体が設計どおりに機能しません。

多くのコンパイラー/インタープリター\"は、GNU C / C ++コンパイラー、Python、Perl、Ruby、さらにはMicrosoft独自のWindows PowerShellから呼び出された場合にのみ認識しますcmd.exe-そして(制限付きで)Windows PowerShellを除いて\""単純な解決策はありませんこの問題に。
基本的に、コマンドラインのどの部分が引用符で囲まれていないと誤って解釈されているかを事前に把握し、それらの部分の^すべてのインスタンスを選択的にエスケープする必要があります& | < >

これとは対照的に、の使用は""安全ですが、されて残念ながら唯一のMicrosoftコンパイラベースの実行可能ファイルおよびバッチファイルでサポートされている(癖は、上述し、バッチファイルの場合)、これは注目すべき除外PowerShellは -次のセクションを参照してください。


cmd.exeまたはPOSIXのようなシェルからPowerShellのCLIを呼び出す:

注:PowerShell 内での引用の処理方法については、下のセクションを参照してください。

呼び出されたときに外部から -例えば、からcmd.exe、どうか、コマンドラインまたはバッチファイルから:

  • PowerShell [コア] v6 +""(に加えて\")を正しく認識するようになりました。これは安全に使用でき、空白を保持します。

    • pwsh -c " ""a & c"".length " 壊れず、正しく降伏する 6
  • Windows PowerShell(最後のバージョンが5.1であるレガシーエディション)は 、Windowsでもより堅牢な/ のみ認識します \""""\"""^""(PowerShellは内部`的に二重引用符で囲まれた文字列のエスケープ文字として使用され、受け入れられ""ますが、下のセクションを参照してください)。

バッチファイルからWindows PowerShell cmd.exe呼び出す:

  • "" 基本的にサポートされていないため、 breaks

    • powershell -c " ""ab c"".length " ->エラー「文字列にターミネータがありません」
  • \"原則的""" 動作しますが安全ではありません

    • powershell -c " \"ab c\".length "意図したとおりに機能します:出力します52スペースに)
    • ので、しかし、それは、安全ではありませんcmd.exe。エスケープしない限り、メタ文字は、コマンドを破る
      powershell -c " \"a& c\".length " 休憩のためには、&のようにエスケープする必要があろう、^&
  • \""安全な、しかしノーマライズインテリア空白望ましくないことができます:

    • powershell -c " \""a& c\"".length "42つのスペースが1に正規化されているため、出力(!)
  • "^""Windows PowerShellの場合、特に安全で空白を維持するのに最適です、PowerShell Core(Windows)ではと同じ\""です。つまり、空白を正規化します。このアプローチを発見したことはVenryxの功績です。

    • powershell -c " "^""a& c"^"".length " 動作します:壊れません-にもかかわらず&- および出力5、つまり、正しく保存された空白。

    • PowerShell Corepwsh -c " "^""a& c"^"".length " 動作しますが4空白スペースを出力します(つまり、空白を正規化します\""

上のUnixライクなプラットフォーム(Linuxでは、MacOSの)、呼び出し[コア] PowerShellをのCLIを、pwsh、よりPOSIXに似た殻のようなbash

使用する必要\"ありますが、これは安全であり、空白を保持します。

$ pwsh -c " \"a&  c|\".length" # OK: 5

関連情報

  • ^二重引用符囲まれた文字列内- 引用符囲まれていない文字列のエスケープ文字としてのみ使用できます^は、特別はなくリテラルとして扱われます。

    • 警告ステートメントに渡されたinパラメータの使用は壊れています^call(これは、call別のバッチファイルまたはバイナリの呼び出しと同じバッチファイル内のサブルーチンの呼び出しのます):
      • ^二重引用符で囲まれた値のインスタンスは、不可解に二重化され、渡される値が変更されます。たとえば、変数%v%にリテラル値が含まれている場合a^b、サブルーチンの(最初のパラメーター)に(!)をcall :foo "%v%"割り当てます。"a^^b"%1:foo
      • 引用符で囲まれていないの使用^callされて完全に壊れたという点では、^もはや特殊文字をエスケープするために使用することはできません。例えば、call foo.cmd a^&b静かに(代わりにリテラル渡すの休憩a&bすぎfoo.cmdずに場合のように、call) -foo.cmdでも呼び出されることはありません、少なくともWindows上で(!) 7。
  • リテラルのエスケープすることは%特殊なケースでいる、残念ながら、文字列が上で指定されているかどうかに応じて、個別の構文を必要とコマンドラインバッチファイル内https://stackoverflow.com/a/31420292/45375を参照してください

    • 短い説明:バッチファイル内では、を使用します%%。コマンドラインで%はエスケープできませんが^引用符で囲まれていない文字列(例:)内の変数名の先頭、末尾、または内部にa echo %^foo%を配置すると、変数の展開(補間)を防ぐことができます。%変数参照の一部ではないコマンドラインのインスタンスは、リテラルとして扱われます(例:)100%
  • 一般に、スペースや特殊文字を含む可能性のある変数値を安全に操作するには、次のようにします

    • 割り当て変数名と値の両方を1組の二重引用符で囲みます。たとえば、set "v=a & b"リテラル値a & bを変数に割り当てます%v%(対照的にset v="a & b"、二重引用符を値の一部にします)。リテラル%インスタンスをエスケープします%%(バッチファイルでのみ機能します-上記を参照)。
    • 参照変数参照二重引用符で囲んで、値が補間されないようにします。たとえば、echo "%v%"の値%v%を補間および印刷しません"a & b"(ただし、二重引用符も常に印刷されることに注意してください)。対照的に、echo %v%はリテラルaをに渡し、コマンドシーケンス演算子としてecho解釈&するため、というコマンドを実行しようとしbます。
      また^callステートメントでの上記の再利用に関する注意事項にも注意してください。
    • 外部プログラムは通常のパラメータの周りに二重引用符を囲む削除の世話をする、しかし、述べたように、バッチファイルで使用するには、(例えば、それを自分で行う必要がある%~1第一のパラメータから二重引用符を囲む削除する)と、悲しいことに、何ら直接的なはありません二重引用符を囲まずにecho変数値を忠実に出力する方法を私は知っています
      • Neil、値に二重引用符が埋め込まれていない限り機能する、forベースの回避策を提供ます。例えば:
        set "var=^&')|;,%!" for /f "delims=" %%v in ("%var%") do echo %%~v
  • cmd.exe単一引用符を文字列区切り文字として認識しませ -それらはリテラルとして扱われ、通常、埋め込まれた空白で文字列を区切るために使用することはできません。また、単一引用符に隣接するトークンとその間のトークンは、によって引用されていないものとして扱われcmd.exe、それに応じて解釈されます。

    • ただし、ターゲットプログラムが最終的に独自の引数解析を実行する場合、Rubyなどの一部のプログラムは、Windowsでも単一引用符で囲まれた文字列を認識します。対照的に、C / C ++実行可能ファイル、PerlおよびPythonはそれらを認識しませ
      ただし、ターゲットプログラムでサポートされている場合でも、その内容がによる不要な解釈から保護されていないため、一重引用符で囲まれた文字列を使用することはお勧めできませんcmd.exe

からの引用 PowerShell

Windows PowerShellは、よりもはるかに高度なシェルでありcmd.exe、長年Windowsの一部でした(そしてPowerShell Coreは、macOSとLinuxにもPowerShellエクスペリエンスをもたらしました)。

PowerShellは、引用に関して内部的に一貫して機能します。

  • 二重引用符で囲まれた文字列内では、`"または""を使用して二重引用符をエスケープします
  • 単一引用符で囲まれた文字列内で、単一''引用符をエスケープするために使用します

これは、PowerShellコマンドラインで、およびPowerShell からPowerShellスクリプトまたは関数にパラメーターを渡すときに機能します

(としては、PowerShellのに逃げ二重引用符を渡し、上述の外部から必要\"、それ以上のこと\""です。

呼び出すときに悲しいことに、外部のPowerShellからプログラムを、あなたは両方のPowerShell独自の引用規則に対応する必要性に直面しているのために脱出するために、ターゲットプログラム:

この問題のある動作についても、この回答で説明および要約されています

double内の引用符引用符で囲まれた文字列引用符

文字列を検討 "3`" of rain"PowerShellが内部的にリテラルに変換する3" of rain

この文字列を外部プログラムに渡す場合は、PowerShell に加え、ターゲットプログラムのエスケープを適用する必要があります。文字列をCプログラムに渡したいとします。これは、埋め込まれた二重引用符が次のようにエスケープされることを期待します\"

foo.exe "3\`" of rain"

どのようにノートの両方が、 `" PowerShellを幸せにする- - \ -ターゲットプログラムを幸せにするために-存在している必要があります。

同じロジックが、""使用する必要があるバッチファイルの呼び出しにも適用されます。

foo.bat "3`"`" of rain"

対照的に、二重引用符で囲まれた文字列に単一引用符を埋め込む場合、エスケープはまったく必要ありません。

単一引用符で囲まれた文字列内の単一引用符は、余分なエスケープを必要としません。PowerShellによるの表現であるを検討してください。'2'' of snow'2' of snow

foo.exe '2'' of snow'
foo.bat '2'' of snow'

PowerShellは、単一引用符で囲まれた文字列を、二重引用符で囲まれた文字列に変換してから、ターゲットプログラムに渡します。

ただし、PowerShellでエスケープする必要がない引用符で囲まれた文字列内の二重引用符は、ターゲットプログラムでもエスケープする必要があります。

foo.exe '3\" of rain'
foo.bat '3"" of rain'

PowerShellのv3は魔法の導入--%オプションと呼ばれ、ストップ・パースのシンボル、それは後に何かを渡すことによって、痛みの一部を緩和し、未解釈のために保存し、ターゲットプログラムにcmd.exeスタイルの環境変数の参照(例えば、%USERNAME%)、されている拡張され、例えば:

foo.exe --% "3\" of rain" -u %USERNAME%

ターゲットプログラムの場合のみ(PowerShellの場合も同様)ではなく、埋め込み"をエスケープする\"だけ\`"で十分であることに注意してください。

ただし、このアプローチ:

  • 環境変数の展開を回避するために、文字をエスケープ することはできません%
  • PowerShell変数と式を直接使用できません。代わりに、コマンドラインは最初のステップで文字列変数に組み込まれ、次にInvoke-Expression2番目のステップで呼び出される必要があります。

このように、PowerShellは多くの進歩にもかかわらず、外部プログラムを呼び出すときにエスケープをはるかに簡単にしていません。ただし、単一引用符で囲まれた文字列のサポートが導入されています。

私はそれがさせるのUnixのモデルに、これまでのスイッチに、Windowsの世界では基本的に可能ですかしらシェルは、すべてのトークン化と引用除去を行う予想通りフロントまで関係なく、ターゲットプログラムのターゲットプログラム呼び出したトークンを渡すことによって、および。


素敵な説明!しかしLiteral use of ^ in double-quoted strings can, be problematic when applying ~ ...、実際にはそうではありません。チルダは、存在する場合にのみ外部引用符を削除します。キャレットを失うことは処理自体の問題です。通常、set "param=%~1"これを解決します。
2015

おかげで、@ jeb、問題は実際に使用に固有のものではありません~-私は私の新しい理解を反映するように私の回答を更新しました-問題を見つけたらコメントしてください。ステートメントに^パラメーターを渡すと自動的に2倍になるという説明はありますcallか?
mklement0 2015

3
MSの誰かがそれを素晴らしいと思ったのは私だけに推測できます。2倍のキャレットは2番目の解析フェーズで自動的に削除されます。しかし、これは引用符では機能せず、特殊文字のエスケープを効果的に防ぐため、大きな失敗でした。call echo cat^^&dogキャレットの量だけでは解決できないようです
jeb

@jebに感謝します。引用していない^withの使用についても考慮していませんでしcallた。それは内と思われるcall echo cat^&dog(単一^適切にエスケープしていること&()ターゲットコマンドecho(!))でも呼び出されることはありません-コマンド全体が静かに失敗します。それに応じて答えを更新しました。
mklement0

素敵な答え。ただし、""エスケープすることはお勧めしません"が、常に推奨します\"(cmd内からそれを使用する危険性の低い方法については、私の回答を参照してください)。定義することを私は公式ドキュメントを知らない""エスケープ引用符が、少なくとも2のように言及している\".NETVS。間違って文書化されていますが、Win32 APIもこれらのルールに従います。
TS

23

グーグルは最終的にその答えを思いついた。バッチでの文字列置換の構文は次のとおりです。

set v_myvar=replace me
set v_myvar=%v_myvar:ace=icate%

これは「私を複製する」を生成します。スクリプトは次のようになります。

@echo off
set v_params=%*
set v_params=%v_params:"=\"%
call bash -c "g++-linux-4.1 %v_params%"

どちらのすべてのインスタンス置き換える"\"、正常にbashのためにエスケープします。


9

mklement0の優れた答えに加えて

ほとんどすべての実行可能ファイルは\"、エスケープされたものとして受け入れ"ます。ただし、cmdでの安全な使用は、DELAYEDEXPANSIONを使用した場合にのみ可能です。
明示的にリテラル"を何らかのプロセスに送信\"し、環境変数に割り当ててから、引用符を渡す必要がある場合はいつでもその変数を使用します。例:

SETLOCAL ENABLEDELAYEDEXPANSION
set q=\"
child "malicious argument!q!&whoami"

注:SETLOCAL ENABLEDELAYEDEXPANSIONバッチファイル内でのみ機能するようです。インタラクティブセッションでDELAYEDEXPANSIONを取得するには、cmd /V:ONます。

バッチファイルがDELAYEDEXPANSIONで機能しない場合は、一時的に有効にすることができます。

::region without DELAYEDEXPANSION

SETLOCAL ENABLEDELAYEDEXPANSION
::region with DELAYEDEXPANSION
set q=\"
echoarg.exe "ab !q! & echo danger"
ENDLOCAL

::region without DELAYEDEXPANSION

あなたはのようにエスケープされている引用符を含む変数から動的なコンテンツを渡したい場合は""、置き換えることができる""\"拡大には:

SETLOCAL ENABLEDELAYEDEXPANSION
foo.exe "danger & bar=region with !dynamic_content:""=\"! & danger"
ENDLOCAL

この置換は%...%スタイル拡張では安全ではありません!

OPの 場合はbash -c "g++-linux-4.1 !v_params:"=\"!"安全版です。


何らかの理由で一時的にDELAYEDEXPANSIONを有効にすることさえできない場合は、以下をお読みください。

使用する \"時々ではなく常に特殊文字をエスケープする必要がある場合、cmd内からのは少し安全です。(一貫性があれば、キャレットを忘れる可能性は低くなります...)

これを実現するには、引用符の前にキャレット(^")を付けます。リテラルはバックラッシ(\^")でさらにエスケープする必要があるため、子プロセスに到達する必要がある引用符です。すべてのシェルメタ文字^&== でエスケープする必要があります^&|=> ^|; >=>^> ; 等

例:

child ^"malicious argument\^"^&whoami^"

出典:誰もがコマンドライン引数を間違った方法で引用している、「より良い引用方法」を参照


動的コンテンツを渡すには、次のことを確認する必要があります。
変数を含むコマンドの部分は、「引用」されていると見なす必要がありますcmd.exe(変数に引用符が含まれている場合、これは不可能です- 記述しないでください%var:""=\"%)。これを実現するため"に、変数の前の最後と"変数の後の最初は^エスケープされません。これら2つの間のcmd-metacharactersは"エスケープしてはなりません。例:

foo.exe ^"danger ^& bar=\"region with %dynamic_content% & danger\"^"

%dynamic_content%一致しない引用符が含まれている可能性がある場合、これは安全ではありません。


わかりました、ありがとう。はい、^断定的に- すべてのメタキャラクターのエスケープは確実に機能、より系統的に適用できます(ただし、選択した身体部分の王室の痛みです)。私はそれに応じて私の答えを更新しました(そしてあなたにクレジットを与えました)。
mklement0 2017年

@ mklement0ありがとうございます!はい、本当に苦痛です。それは迷惑で、メタキャラクターを忘れるのはまだ簡単です(したがって、私は主にこの!q!方法を使用します)。注:最後の編集後、回答に若干の一貫性がありません:冒頭付近で「使用しないでください」と言います^"。後で^"回避策の一部として使用します。多分あなたは両方の方法を説明できますか?(1)すべてのメタ文字をエスケープする(より体系的に)/(2)「引用符で囲まれていない」領域でメタ文字を選択的にエスケープする(動的コンテンツを渡すために必要な場合があります。たとえば、foo.exe ^"danger ^& bar=\"%dynamic_content%\"^"この方法で変数がcmdに引用される)
TS

良い点、ありがとう-回答が更新されました。また、MSコンパイラがとの両方\"を受け入れることも明確にしました""。より複雑な変数ベースのアプローチに対するあなたの回答にリンクしました。それが今意味をなすかどうか教えてください。
mklement0

1
@ mklement0あなたの答えは常に理にかなっています:-)私は可能な改善のためにいくつかのアイデアを与えたかっただけです。私も%dynamic_content%私の答えに例を追加しました。それは十分に詳細だと思いますか、それとももっと説明しなければなりませんか?
TS

3
よろしくお願いします。をローカライズするのは良い考えsetlocal delayedexpansionですが、ブロックをendlocal(引数なしで)終了する必要があります。正直言って、私の頭が回転し始めて、あなたのギストを見た。ここでは実際にエッジケースを扱っており、将来の読者は2つの答えの間に必要なものがすべて見つかると思います。
mklement0 2017年

0

文字列がすでに引用符で囲まれている場合は、別の引用符を使用してそのアクションを無効にします。

echo "Insert tablename(col1) Values('""val1""')" 

-3

たとえば、バッチファイルから実行されるアンリアルエンジンオートメーションツールの場合-これは私にとってうまくいきました

例:-cmdline = "-Messaging" -device = device -addcmdline = "-SessionId = session -SessionOwner = 'owner' -SessionName = 'Build' -dataProviderMode = local -LogCmds = 'LogCommodity OFF' -execcmds = 'オートメーションリスト; runtests tests + separated + by + T1 + T2; quit '"-run

これが私のために働いた誰かを助けることを願っています。


あなたが学んだ概念が明確な例に共有しようとしているのではなく、あなたの作品からのほとんど何も関係のないコピー貼り付けではないことを理解するようにしてください。
run_the_race
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.