Das zweite Dokument, das Peter Mortensen in seinem Kommentar zur Antwort von Codesmith zitierte, machte die Dinge für mich viel klarer. Dieses Dokument wurde von windowsinspired.com geschrieben. Der Link wiederholte sich: Ein besserer Weg, um das Zitieren und Escaping von Windows-Befehlszeilenargumenten zu verstehen .
Einige weitere Versuche und Irrtümer führen zu der folgenden Richtlinie:
Entkomme jedem doppelten Zitat "
mit einem Caret ^
. Wenn Sie andere Zeichen mit besonderer Bedeutung für die Windows - Befehlsshell wollen (zB <
, >
, |
, &
) als reguläre Zeichen stattdessen interpretiert wird, dann sie mit einem caret zu entkommen, auch.
Wenn Sie möchten, dass Ihr Programm foo den Befehlszeilentext empfängt "a\"b c" > d
und seine Ausgabe in die Datei out.txt umleitet , starten Sie Ihr Programm wie folgt über die Windows-Befehlsshell:
foo ^"a\^"b c^" ^> d > out.txt
Wenn foo\"
als wörtliches doppeltes Anführungszeichen interpretiert und erwartet, dass nicht umschlossene doppelte Anführungszeichen Argumente begrenzen, die Leerzeichen enthalten, interpretiert foo den Befehl so, dass ein Argument a"b c
, ein Argument >
und ein Argument angegeben werden d
.
Wenn foo stattdessen ein doppeltes Anführungszeichen ""
als wörtliches doppeltes Anführungszeichen interpretiert , starten Sie Ihr Programm als
foo ^"a^"^"b c^" ^> d > out.txt
Die wichtigste Erkenntnis aus dem zitierten Dokument ist, dass für die Windows-Befehlsshell ein nicht entkoppeltes doppeltes Anführungszeichen den Wechsel zwischen zwei möglichen Zuständen auslöst.
Einige weitere Versuche und Irrtümer implizieren, dass im Ausgangszustand die Umleitung (zu einer Datei oder Pipe) erkannt wird und ein Caret ^
einem doppelten Anführungszeichen entgeht und das Caret aus der Eingabe entfernt wird. Im anderen Zustand wird die Umleitung nicht erkannt und ein Caret entgeht keinem doppelten Anführungszeichen und wird nicht entfernt. Nennen wir diese Zustände "außen" bzw. "innen".
Wenn Sie die Ausgabe Ihres Befehls umleiten möchten, muss sich die Befehlsshell im Außenzustand befinden, wenn sie die Umleitung erreicht. Daher muss vor der Umleitung eine gerade Anzahl von doppelten Anführungszeichen (durch Caret) stehen. foo "a\"b " > out.txt
funktioniert nicht - die Befehlsshell übergibt das gesamte als kombinierte Befehlszeilenargumente "a\"b " > out.txt
an foo , anstatt nur zu übergeben "a\"b "
und die Ausgabe an out.txt umzuleiten .
foo "a\^"b " > out.txt
funktioniert auch nicht, da das Caret ^
im inneren Zustand angetroffen wird, in dem es sich um ein gewöhnliches Zeichen und nicht um ein Fluchtzeichen handelt, und daher "a\^"b " > out.txt
an foo übergeben wird .
Die einzige Möglichkeit, die (hoffentlich) immer funktioniert, besteht darin, die Befehlsshell immer im externen Zustand zu halten, da dann die Umleitung funktioniert.
Wenn Sie keine Umleitung benötigen (oder andere Zeichen mit besonderer Bedeutung für die Befehlsshell), können Sie auf die Carets verzichten. Wenn foo\"
als wörtliches doppeltes Anführungszeichen interpretiert wird , können Sie es als bezeichnen
foo "a\"b c"
Dann empfängt foo"a\"b c"
als kombiniertes Argument Text und kann ihn als einzelnes Argument gleich interpretieren a"b c
.
Nun - endlich - zur ursprünglichen Frage. Wirdmyscript '"test"'
von der Windows-Befehlsshell aufgerufen und'"test"'
an MyScript übergeben . Anscheinend interpretiert Myscript die einfachen und doppelten Anführungszeichen als Argumenttrennzeichen und entfernt sie. Sie müssen herausfinden, was Myscript als wörtliches Anführungszeichen akzeptiert, und dies dann in Ihrem Befehl angeben, ^
um alle Zeichen zu umgehen , die für die Windows-Befehlsshell eine besondere Bedeutung haben. Da dies myscript
auch unter Unix verfügbar ist, reicht es vielleicht aus \"
. Versuchen
myscript \^"test\^"
oder, wenn Sie keine Umleitung benötigen,
myscript \"test\"
myscript \"test\"