Citations et guillemets doubles

94

Comment échapper correctement les guillemets dans la -paramvaleur dans la ligne de commande suivante?

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

Cela échoue bien sûr. J'ai essayé d'échapper aux guillemets (simples et doubles) en utilisant le caractère d'échappement `et j'ai fait diverses combinaisons, mais rien ne fonctionne.

eetawil
la source
Voir aussi Invoke-Expression considérée comme nuisible .
Peter Mortensen
@PeterMortensen il y a un problème avec cet article, c'est qu'il ne semble pas y avoir de meilleur moyen, lorsque vous souhaitez lancer une application native et passer un paramètre qui inclut un guillemet double comme argument
Andrew Savinykh
Savinykh @ Andrew: Une façon est de le lancer à travers cmd à la place: $someCommandStringWithDoubleQuotes | cmd. Cela fonctionne en fait à partir de scripts PowerShell (par exemple en invoquant CMake (qui nécessite les guillemets doubles (sinon, il échouera silencieusement))). Une alternative à CMD est bash.exe ( MinGW ) - mais il peut être très, très lent à démarrer dans certaines circonstances.
Peter Mortensen

Réponses:

59

Échapper à de tels paramètres est généralement source de frustration et ressemble beaucoup à un temps perdu. Je vois que vous êtes sur la v2 donc je suggérerais d'utiliser une technique que Joel "Jaykul" Bennet a bloguée il y a quelque temps .

Pour faire court: vous enroulez simplement votre chaîne avec @ '...' @:

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

(Notez que j'ai supposé quels guillemets sont nécessaires et quelles choses vous tentiez d'échapper.) Si vous voulez travailler avec la sortie, vous pouvez ajouter le -NoNewWindowcommutateur.

BTW: c'était un problème si important que depuis la v3, vous pouvez utiliser --%pour empêcher l'analyseur PowerShell de faire quoi que ce soit avec vos paramètres:

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

... devrait bien fonctionner là-bas (avec la même hypothèse).

BartekB
la source
Merci pour votre réponse. processus de démarrage, peu importe comment j'ai essayé, toujours plaint. Donc j'ai fait cmd / C $ cmd (où $ cmd est ma commande entière, y compris le .exe.). J'utilise PowerShell 2.0. Même la chaîne ici ne fonctionnait pas si je me souviens bien.
eetawil
3
Cela semble inutilement compliqué par rapport à l'utilisation du backtick (`) pour échapper les guillemets doubles.
saille
6
Cela fonctionne très bien tant que vous suivez les règles attendues. Le premier @ 'doit être sur "ligne 1", votre paramètre doit être sur "ligne 2" et la fin "@ doit être sur" ligne 3 ". La fin '@ ne peut pas avoir d'espace devant elle. Mec, cette syntaxe est difficile!
Ian Newland
Fonctionne très bien! Si vous devez développer des variables dans votre chaîne, vous pouvez utiliser @"et à la "@place.
browly
97

L'utilisation du backtick (`) fonctionne très bien pour moi si je les place aux endroits suivants:

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

$cmd retourne comme:

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

C'est ce que tu cherchais?

L'erreur que PowerShell m'a donnée faisait référence à un jeton inattendu `` sort1 '', et c'est ainsi que j'ai déterminé où placer les backticks.

La syntaxe @ '...' @ s'appelle une "chaîne ici" et retournera exactement ce qui est entré. Vous pouvez également les utiliser pour renseigner des variables de la manière suivante:

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

Les symboles d'ouverture et de fermeture doivent figurer sur leur propre ligne, comme indiqué ci-dessus.

Owen B
la source
Désolé pour le retard ... la façon dont je l'ai fait fonctionner est d'appeler finalement cmd / C "MYCOMMAND" depuis PowerShell. Cela ne fonctionnait pas en utilisant directement PowerShell.
eetawil
1
Mais ne supprime-t-il pas Invoke-Expressionles guillemets doubles du $cmdmoment où il est appelé? Ou comment avez-vous utilisé $cmdsans utiliser Invoke-Expression?
Peter Mortensen
8

Je me suis retrouvé dans une situation similaire aujourd'hui en essayant d'exécuter une commande via un module Node.js:

J'utilisais PowerShell et j'essayais d'exécuter:

command -e 'func($a)'

Mais avec les symboles supplémentaires, PowerShell manipulait les arguments. Pour corriger, je coche en arrière les guillemets doubles échappés:

command -e `"func($a)`"
pranspach
la source
2
intéressant: "['`"][^'`"]['`"]"fonctionne… mais '[`'"][^`'"][`'"]'pas! me rendait fou
David J