Unikanie cudzysłowów i cudzysłowów

94

Jak prawidłowo usunąć cudzysłowy w -paramwartości w następującym wierszu poleceń?

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

To oczywiście zawodzi. Próbowałem uniknąć cudzysłowów (pojedynczych i podwójnych), używając znaku ucieczki `i wykonałem różne kombinacje, ale nic nie działa.

eetawil
źródło
Zobacz także Invoke-Expression uważane za szkodliwe .
Peter Mortensen
@PeterMortensen problem z tym artykułem polega na tym, że nie ma lepszego sposobu na uruchomienie natywnej aplikacji i przekazanie parametru zawierającego podwójny cudzysłów jako argument
Andrew Savinykh
@Andrew Savinykh: Jednym ze sposobów jest uruchomienie go przez cmd zamiast: $someCommandStringWithDoubleQuotes | cmd. To faktycznie działa ze skryptów PowerShell (np. Wywołanie CMake (co wymaga podwójnych cudzysłowów (w przeciwnym razie po cichu zakończy się niepowodzeniem))). Alternatywą dla CMD jest bash.exe ( MinGW ) - ale w niektórych okolicznościach może się on uruchamiać bardzo, bardzo wolno.
Peter Mortensen

Odpowiedzi:

60

Ucieczka przed parametrami jest zwykle źródłem frustracji i sprawia wrażenie straconego czasu. Widzę, że korzystasz z wersji 2, więc sugerowałbym użycie techniki, o której jakiś czas temu pisał na blogu Joel „Jaykul” Bennet .

Krótko mówiąc: po prostu owijasz swój ciąg znakiem @ '...' @:

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

(Pamiętaj, że założyłem, które cudzysłowy są potrzebne i przed którymi rzeczami próbujesz uciec). Jeśli chcesz pracować z wynikiem, możesz dodać-NoNewWindow przełącznik.

BTW: to był tak ważny problem, że od wersji v3 możesz użyć, --%aby zatrzymać parser PowerShell przed robieniem czegokolwiek z twoimi parametrami:

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

... powinno tam działać dobrze (przy tym samym założeniu).

BartekB
źródło
Dzięki za odpowiedź. bez względu na to, jak próbowałem, zawsze narzekałem. Więc zrobiłem cmd / C $ cmd (gdzie $ cmd to całe moje polecenie, w tym .exe.). Używam PowerShell 2.0. Nawet łańcuch tutaj nie działał, jeśli dobrze pamiętam.
eetawil
3
Wydaje się to niepotrzebnie skomplikowane w porównaniu z używaniem znaku wstecznego (`) do unikania podwójnych cudzysłowów.
wypłynąć
6
Działa to świetnie, o ile przestrzegasz zasad, których oczekuje. Pierwszy @ 'musi znajdować się w „linii 1”, parametr musi znajdować się w „linii 2”, a koniec „@ musi znajdować się w„ linii 3 ”. Końcówka „@ nie może mieć przed sobą spacji. Człowieku, ta składnia jest wybredna!
Ian Newland
Działa świetnie! Jeśli potrzebujesz rozwinąć zmienne w swoim ciągu, możesz zamiast tego użyć @"i "@.
browly
97

Użycie znaku wstecznego (`) działa dobrze, jeśli umieszczę je w następujących miejscach:

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

$cmd wraca jako:

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

Czy tego szukałeś?

Błąd, który dał mi PowerShell, odnosił się do nieoczekiwanego tokena „sort1” i w ten sposób ustaliłem, gdzie umieścić znaki grawitacyjne.

Składnia @ '...' @ jest nazywana „ciągiem znaków” i zwróci dokładnie to, co zostało wprowadzone. Można ich również używać do wypełniania zmiennych w następujący sposób:

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

Symbole otwierania i zamykania muszą znajdować się w osobnych wierszach, jak pokazano powyżej.

Owen B.
źródło
Przepraszam za opóźnienie ... sposób, w jaki to zadziałało, to wreszcie wywołanie cmd / C „MYCOMMAND” z PowerShell. Nie działało bezpośrednio przy użyciu PowerShell.
eetawil
1
Ale czy nie usuwa Invoke-Expressionpodwójnych cudzysłowów z $cmdmomentu wywołania? Albo jak używałeś $cmdbez używania Invoke-Expression?
Peter Mortensen
8

Znalazłem się dzisiaj w podobnej sytuacji, próbując uruchomić polecenie za pośrednictwem modułu Node.js:

Używałem PowerShell i próbowałem uruchomić:

command -e 'func($a)'

Ale z dodatkowymi symbolami PowerShell manipulował argumentami. Aby to naprawić, zaznaczam wstecz znaki zmiany znaczenia w cudzysłowie:

command -e `"func($a)`"
pranspach
źródło
2
ciekawe: "['`"][^'`"]['`"]"działa… ale '[`'"][^`'"][`'"]'nie działa! doprowadzało mnie do szału
David J