Escape-Anführungszeichen und doppelte Anführungszeichen

92

Wie kann ich die Anführungszeichen im -paramWert in der folgenden Befehlszeile ordnungsgemäß umgehen ?

$cmd="\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'""
Invoke-Expression $cmd 

Das scheitert natürlich. Ich habe versucht, die Anführungszeichen (einfach und doppelt) mit dem Escape-Zeichen `zu umgehen und habe verschiedene Kombinationen durchgeführt, aber nichts funktioniert.

Eetawil
quelle
Siehe auch Invoke-Expression als schädlich .
Peter Mortensen
@ PeterMortensen gibt es Problem mit diesem Artikel, ist, dass es keinen besseren Weg zu geben scheint, wenn Sie eine native Anwendung starten und einen Parameter übergeben möchten, der ein doppeltes Anführungszeichen als Argument enthält
Andrew Savinykh
@ Andrew Savinykh: Eine Möglichkeit besteht darin, es stattdessen über cmd zu starten : $someCommandStringWithDoubleQuotes | cmd. Dies funktioniert tatsächlich mit PowerShell-Skripten (z. B. Aufrufen von CMake (dies erfordert doppelte Anführungszeichen (andernfalls schlägt dies stillschweigend fehl))). Eine Alternative zu CMD ist bash.exe ( MinGW ) - unter bestimmten Umständen kann der Start jedoch sehr, sehr langsam sein.
Peter Mortensen

Antworten:

58

Das Entkommen solcher Parameter ist normalerweise eine Quelle der Frustration und fühlt sich sehr nach Zeitverschwendung an. Ich sehe, dass Sie auf v2 sind, also würde ich vorschlagen, eine Technik zu verwenden, die Joel "Jaykul" Bennet vor einiger Zeit gebloggt hat .

Lange Rede, kurzer Sinn: Sie wickeln Ihre Zeichenfolge einfach mit @ '...' @:

Start-Process \\server\toto.exe @'
-batch=B -param="sort1;parmtxt='Security ID=1234'"
'@

(Beachten Sie, dass ich davon ausgegangen bin , welche Anführungszeichen benötigt werden und welchen Dingen Sie entkommen wollten.) Wenn Sie mit der Ausgabe arbeiten möchten, möchten Sie möglicherweise den -NoNewWindowSchalter hinzufügen .

Übrigens: Dies war ein so wichtiges Problem, dass Sie seit Version 3 --%den PowerShell-Parser daran hindern können , irgendetwas mit Ihren Parametern zu tun:

\\server\toto.exe --% -batch=b -param="sort1;paramtxt='Security ID=1234'"

... sollte dort gut funktionieren (mit der gleichen Annahme).

BartekB
quelle
Danke für deine Antwort. Start-Prozess, egal wie ich es versucht habe, hat sich immer beschwert. Also habe ich cmd / C $ cmd gemacht (wobei $ cmd mein gesamter Befehl einschließlich der EXE-Datei ist). Ich benutze Powershell 2.0. Sogar der Here-String hat nicht funktioniert, wenn ich mich richtig erinnere.
Eetawil
3
Dies scheint unnötig kompliziert im Vergleich zur Verwendung von Backtick (`), um doppelte Anführungszeichen zu vermeiden.
Saille
6
Dies funktioniert hervorragend, solange Sie die erwarteten Regeln befolgen. Das erste @ 'muss in "Zeile 1" stehen, Ihr Parameter muss in "Zeile 2" stehen und das Ende' @ muss in "Zeile 3" stehen. Die Endung '@ darf keine Leerzeichen enthalten. Mann diese Syntax ist wählerisch!
Ian Newland
Funktioniert super! Wenn Sie Variablen in Ihrer Zeichenfolge erweitern müssen, können Sie stattdessen @"und "@verwenden.
Browly
94

Die Verwendung des Backticks (`) funktioniert für mich einwandfrei, wenn ich sie an folgenden Stellen platziere:

$cmd="\\server\toto.exe -batch=B -param=`"sort1;parmtxt='Security ID=1234'`""

$cmd gibt zurück als:

\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'"

Haben Sie danach gesucht?

Der Fehler, den PowerShell mir gab, bezog sich auf ein unerwartetes Token 'sort1', und so bestimmte ich, wo die Backticks abgelegt werden sollten.

Die @ '...' @ -Syntax wird als "here string" bezeichnet und gibt genau das zurück, was eingegeben wurde. Sie können sie auch verwenden, um Variablen auf folgende Weise zu füllen:

$cmd=@'
"\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'""
'@

Die Öffnungs- und Schließsymbole müssen wie oben gezeigt in einer eigenen Zeile stehen.

Owen B.
quelle
Entschuldigung für die Verzögerung ... die Art und Weise, wie ich es zum Laufen gebracht habe, ist, cmd / C endlich "MYCOMMAND" von Powershell zu nennen. Es hat nicht direkt mit Powershell funktioniert.
Eetawil
1
Aber werden Invoke-Expressiondie doppelten Anführungszeichen nicht entfernt, $cmdwenn sie aufgerufen werden? Oder wie haben Sie $cmdohne verwendet Invoke-Expression?
Peter Mortensen
8

Ich befand mich heute in einer ähnlichen Situation, als ich versuchte, einen Befehl über ein Node.js-Modul auszuführen:

Ich habe die PowerShell verwendet und versucht, Folgendes auszuführen:

command -e 'func($a)'

Aber mit den zusätzlichen Symbolen hat PowerShell die Argumente entstellt. Um dies zu beheben, habe ich die doppelten Anführungszeichen zurückgesetzt:

command -e `"func($a)`"
Pranspach
quelle
1
interessant: "['`"][^'`"]['`"]"funktioniert… aber '[`'"][^`'"][`'"]'nicht! hat mich verrückt gemacht
David J