Aspas de escape e aspas duplas

94

Como faço para escapar corretamente das aspas no -paramvalor na linha de comando a seguir?

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

Isso, claro, falha. Tentei escapar das aspas (simples e duplas) usando o caractere de escape `e fiz várias combinações, mas nada está funcionando.

Eetawil
fonte
Veja também Invoke-Expression considerado prejudicial .
Peter Mortensen,
@PeterMortensen, o problema com este artigo, é que não parece haver uma maneira melhor, quando você deseja iniciar um aplicativo nativo e passar um parâmetro que inclui aspas duplas como argumento
Andrew Savinykh
@ Andrew Savinykh: Uma maneira é lançá-lo através de cmd em vez disso: $someCommandStringWithDoubleQuotes | cmd. Na verdade, isso funciona a partir de scripts do PowerShell (por exemplo, invocar CMake (que requer aspas duplas (caso contrário, falhará silenciosamente)). Uma alternativa ao CMD é bash.exe ( MinGW ) - mas pode ser muito, muito lento para iniciar em algumas circunstâncias.
Peter Mortensen

Respostas:

59

Escapar de parâmetros como esse geralmente é fonte de frustração e parece uma perda de tempo. Vejo que você está na v2, então sugiro usar uma técnica que Joel "Jaykul" Bennet postou no blog há algum tempo .

Resumindo: você acabou de enrolar sua corda com @ '...' @:

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

(Lembre-se de que presumi quais aspas são necessárias e de quais coisas você estava tentando escapar.) Se quiser trabalhar com a saída, você pode adicionar a -NoNewWindowopção.

BTW: esta era uma questão tão importante que desde a v3 você pode usar --%para impedir o analisador PowerShell de fazer qualquer coisa com seus parâmetros:

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

... deve funcionar bem lá (com a mesma suposição).

BartekB
fonte
Obrigado pela sua resposta. start-process não importa como eu tentei, sempre reclamei. ENTÃO fiz cmd / C $ cmd (onde $ cmd é meu comando inteiro, incluindo o .exe.). Estou usando o PowerShell 2.0. Mesmo a string here não funcionou, se bem me lembro.
eetawil
3
Isso parece desnecessariamente complicado em comparação com o uso de crase (`) para escapar das aspas duplas.
Saille
6
Isso funciona muito bem, desde que você siga as regras que ele espera. O primeiro @ 'deve estar na "linha 1", seu parâmetro deve estar na "linha 2" e o final' @ deve estar na "linha 3". O final '@ não pode ter espaços antes dele. Cara, essa sintaxe é exigente!
Ian Newland
Funciona bem! Se você precisar expandir variáveis ​​em sua string, você pode usar @"e em seu "@lugar.
browly
96

Usar o crase (`) funciona bem para mim se eu colocá-los nos seguintes lugares:

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

$cmd retorna como:

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

É isso que você estava procurando?

O erro que o PowerShell me deu se refere a um token inesperado 'sort1', e é assim que eu determinei onde colocar os crases.

A sintaxe @ '...' @ é chamada de "string here" e retornará exatamente o que foi inserido. Você também pode usá-los para preencher variáveis ​​da seguinte maneira:

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

Os símbolos de abertura e fechamento devem estar em suas próprias linhas, conforme mostrado acima.

Owen B
fonte
Desculpe pela demora ... a maneira que fiz funcionar é finalmente chamar cmd / C de "MYCOMMAND" do PowerShell. Não funcionou usando o PowerShell diretamente.
eetawil
1
Mas não Invoke-Expressionremove as aspas duplas de $cmdquando é invocado? Ou como você usou $cmdsem usar Invoke-Expression?
Peter Mortensen,
8

Eu me encontrei em uma situação semelhante hoje ao tentar executar um comando por meio de um módulo Node.js.

Eu estava usando o PowerShell e tentando executar:

command -e 'func($a)'

Mas com os símbolos extras, o PowerShell estava destruindo os argumentos. Para corrigir, marquei aspas duplas com escape:

command -e `"func($a)`"
pranspach
fonte
2
interessante: "['`"][^'`"]['`"]"funciona… mas '[`'"][^`'"][`'"]'não funciona! estava me deixando louco
David J