144 votes

Échapper aux guillemets doubles dans le paramètre

Sous Unix, je pouvais exécuter myscript '"test"' et j'aurais "test" .

Dans Windows cmd Je reçois 'test' .

Comment puis-je passer des guillemets doubles en tant que paramètre ? J'aimerais savoir comment faire cela manuellement à partir d'un fichier cmd pour que je n'aie pas à écrire un programme pour tester mon programme.

3 votes

Cela fait des années que je n'ai pas touché à une machine Windows, mais le caractère d'échappement standard (barre oblique inversée) ne fonctionne-t-il pas ? myscript \"test\"

0 votes

Non. Je reçois \test\. Je soupçonne que c'est parce que Windows utilise \ au lieu de /, de sorte que la barre oblique inversée ne peut pas être utilisée comme échappatoire. Mais je ne sais pas vraiment.

1 votes

Je ne sais pas quelle version de Windows vous utilisez, mais le système "\" fonctionne bien sous Windows 7 (Ultimate). Il y a une autre façon de le faire, en traitant les guillemets multiples (c'est-à-dire que """ devient " ou quelque chose comme ça), mais je n'arrive pas à savoir quand et comment cela fonctionne.

236voto

AUTO Points 709

Une autre façon d'échapper aux guillemets (bien qu'elle ne soit probablement pas préférable), que j'ai trouvée utilisée à certains endroits, est la suivante utiliser plusieurs guillemets . Dans le but de rendre lisible le code des autres, je vais expliquer.

Voici un ensemble de règles de base :

  1. Lorsqu'ils ne sont pas entourés de groupes de guillemets, les espaces séparent les paramètres :
    program param1 param2 param 3 transmettra quatre paramètres à program.exe :
         param1 , param2 , param y 3 .
  2. Un groupe à double guillemet ignore les espaces comme séparateurs de valeurs lorsqu'il transmet des paramètres aux programmes :
    program one two "three and more" transmettra trois paramètres à program.exe :
         one , two y three and more . _Maintenant, pour expliquer une partie de la confusion :_4. Les groupes de guillemets qui apparaissent directement adjacents à du texte non entouré de guillemets se réunissent en un seul paramètre :
    hello"to the entire"world agit comme un paramètre : helloto the entireworld . _Remarque : la règle précédente n'implique PAS que deux groupes de guillemets doubles peuvent apparaître directement adjacents l'un à l'autre._6. Tout guillemet double directement après une citation finale est traité comme (ou comme une partie de) du texte brut non enveloppé qui est adjacent au groupe de guillemets doubles, mais un seul guillemet double :
    "Tim says, ""Hi!""" agira comme un seul paramètre : Tim says, "Hi!"

Il existe donc trois types de guillemets différents : les guillemets ouvrants, les guillemets fermants et les guillemets en clair.
Voici le détail de cette dernière ligne confuse :

"   open double-quote group
T   inside ""s
i   inside ""s
m   inside ""s
    inside ""s - space doesn't separate
s   inside ""s
a   inside ""s
y   inside ""s
s   inside ""s
,   inside ""s
    inside ""s - space doesn't separate
"   close double-quoted group
"   quote directly follows closer - acts as plain unwrapped text: "
H   outside ""s - gets joined to previous adjacent group
i   outside ""s - ...
!   outside ""s - ...
"   open double-quote group
"   close double-quote group
"   quote directly follows closer - acts as plain unwrapped text: "

Ainsi, le texte réunit effectivement quatre groupes de personnages (un avec rien, cependant) :
Tim says,  est le premier, enveloppé pour échapper aux espaces
"Hi! est le deuxième, non enveloppé (il n'y a pas d'espace)
 est le troisième, un groupe de guillemets n'enveloppant rien.
" est la quatrième, la citation fermée non enveloppée.

Comme vous pouvez le constater, le groupe de guillemets n'enveloppant rien est toujours nécessaire car, sans lui, le guillemet suivant ouvrirait un groupe de guillemets au lieu d'agir comme du texte brut.

À partir de là, il devrait être possible de reconnaître que, à l'intérieur et à l'extérieur des guillemets, trois guillemets doubles agissent comme un guillemet double non encodé en texte clair :

"Tim said to him, """What's been happening lately?""""

imprimera Tim said to him, "What's been happening lately?" comme prévu. Par conséquent, trois guillemets peuvent toujours être utilisés de manière fiable comme échappement.
Toutefois, en le comprenant, vous remarquerez que les quatre guillemets à la fin peuvent être réduits à deux seulement, car techniquement, cela ajoute un autre groupe vide inutile de guillemets doubles.

Voici quelques exemples pour conclure :

program a b                       REM sends (a) and (b)
program """a"""                   REM sends ("a")
program """a b"""                 REM sends ("a) and (b")
program """"Hello,""" Mike said." REM sends ("Hello," Mike said.)
program ""a""b""c""d""            REM sends (abcd) since the "" groups wrap nothing
program "hello to """quotes""     REM sends (hello to "quotes")
program """"hello world""         REM sends ("hello world")
program """hello" world""         REM sends ("hello world")
program """hello "world""         REM sends ("hello) and (world")
program "hello ""world"""         REM sends (hello "world")
program "hello """world""         REM sends (hello "world")

Note finale : je n'ai pas lu ces informations dans un quelconque tutoriel - je les ai toutes trouvées en expérimentant. Par conséquent, mon explication peut ne pas être vraie en interne. Néanmoins, tous les exemples ci-dessus fonctionnent comme prévu, validant ainsi (mais ne prouvant pas) ma théorie.

J'ai testé cela sur Windows 7, 64bit en utilisant uniquement des appels *.exe avec passage de paramètres (pas *.bat, mais je suppose que cela fonctionne de la même manière).

31voto

mousio Points 4039

Je ne peux pas reproduire rapidement les symptômes : si j'essaie de myscript '"test"' avec un fichier batch myscript.bat contenant juste @echo.%1 ou même @echo.%~1 Je reçois tous les devis : '"test"'

Vous pouvez peut-être essayer le caractère d'échappement ^ comme ça : myscript '^"test^"' ?

1 votes

Pour reproduire, vous pouvez créer un fichier test.js qui contient WScript.Echo(WScript.Arguments(0)) et ouvrir cmd et le type wscript test.js '^"test^"' . Vous constaterez que la carotte et les guillemets sont supprimés.

3 votes

Alors peut-être que les réponses à cette question pourrait vous aider davantage ?

2 votes

Ha ! Je n'aurais jamais deviné que c'était wscript C'est la faute de l'entreprise ! Laissez-le à Windows :)

28voto

smwikipedia Points 5491

Essayez ça :

myscript """test"""

"" échapper à un seul " dans le paramètre.

5 votes

Ce n'est pas tout à fait correct. Essayez myscript """test test""" et cela ne fonctionne pas (le premier paramètre est transmis en tant que "test . En fait, il vous faut trois devis : myscript """"test test"" La troisième citation à la fin peut être sautée, cependant.

0 votes

Que faire si je dois supprimer tous les guillemets ici et placer la valeur du paramètre dans une chaîne utilisée dans un filtre de requête de sélection ? Quelqu'un peut-il m'aider ?

2 votes

Ce n'est peut-être pas la bonne réponse à cette question, mais ça m'a aidé quand j'ai eu besoin de réussir. char **argv de mon lanceur C vers un autre processus en utilisant des fonctions comme spawn o exec . Merci. :-)

7voto

Louis Strous Points 31

Le 2ème document cité par Peter Mortensen dans son commentaire sur la réponse de Codesmith a rendu les choses beaucoup plus claires pour moi. Ce document a été écrit par windowsinspired.com. Le lien a été répété : Une meilleure façon de comprendre la citation et l'échappement des arguments de la ligne de commande Windows .

Quelques essais et erreurs supplémentaires permettent d'aboutir à la ligne directrice suivante :

Échapper à chaque guillemet double " avec un caret ^ . Si vous souhaitez utiliser d'autres caractères ayant une signification particulière pour l'interpréteur de commandes Windows (par exemple , < , > , | , & ) pour qu'ils soient interprétés comme des caractères normaux à la place, alors échappez-les également avec un caret.

Si vous voulez que votre programme foo pour recevoir le texte de la ligne de commande "a\"b c" > d et redirige sa sortie vers le fichier out.txt puis lancez votre programme comme suit à partir du shell de commande Windows :

foo ^"a\^"b c^" ^> d > out.txt

Si foo interprète \" en tant que guillemet double littéral et s'attend à ce que des guillemets doubles non récupérés délimitent les arguments qui incluent des espaces, alors foo interprète la commande comme spécifiant un seul argument a"b c un argument > et un argument d .

Si au contraire foo interprète un guillemet double "" en tant que guillemet double littéral, puis lancez votre programme en tant que

foo ^"a^"^"b c^" ^> d > out.txt

La principale conclusion du document cité est que, pour l'interpréteur de commandes Windows, un guillemet double non masqué déclenche la commutation entre deux états possibles.

Après quelques essais et erreurs supplémentaires, il s'avère que dans l'état initial, la redirection (vers un fichier ou un tuyau) est reconnue et un signe d'insertion. ^ échappe un guillemet double et le signe d'insertion est supprimé de l'entrée. Dans l'autre état, la redirection n'est pas reconnue et un signe d'insertion n'échappe pas à un guillemet double et n'est pas supprimé. Nous appellerons ces états "extérieur" et "intérieur", respectivement.

Si vous voulez rediriger la sortie de votre commande, l'interpréteur de commande doit être dans l'état extérieur lorsqu'il atteint la redirection, et il doit donc y avoir un nombre pair de guillemets doubles non masqués (par caret) précédant la redirection. foo "a\"b " > out.txt ne fonctionnera pas -- l'interpréteur de commandes transmet l'intégralité de la commande "a\"b " > out.txt a foo comme arguments combinés de la ligne de commande, au lieu de transmettre uniquement "a\"b " et en redirigeant la sortie vers out.txt .

foo "a\^"b " > out.txt ne fonctionnera pas non plus, car le signe d'insertion ^ est rencontré dans l'état intérieur où il est un caractère ordinaire et non un caractère d'échappement, donc "a\^"b " > out.txt est transmis à foo .

La seule façon qui fonctionne toujours (espérons-le) est de garder le shell de commande toujours dans l'état extérieur, car alors la redirection fonctionne.

Si vous n'avez pas besoin de redirection (ou d'autres caractères ayant une signification particulière pour le shell de commande), vous pouvez vous passer des carets. Si foo interprète \" comme un guillemet double littéral, alors vous pouvez l'appeler en tant que

foo "a\"b c"

Puis foo reçoit "a\"b c" comme son texte d'arguments combinés et peut l'interpréter comme un seul argument égal à a"b c .

Maintenant, et pour finir, à la question initiale. myscript '"test"' appelé depuis le shell de commande Windows passe '"test"' a myscript . Apparemment, myscript interprète les guillemets simples et doubles comme des délimiteurs d'arguments et les supprime. Vous devez déterminer ce que myscript accepte comme un guillemet double littéral et le spécifie ensuite dans votre commande, en utilisant ^ pour échapper à tous les caractères qui ont une signification spéciale pour le shell de commande Windows. Étant donné que myscript est également disponible sur Unix, peut-être \" fait l'affaire. Essayez

myscript \^"test\^"

ou, si vous n'avez pas besoin de redirection,

myscript \"test\"

3voto

Zimba Points 156

J'appelle powershell à partir de cmd, et le passage des guillemets et des escapes ne fonctionne pas ici. L'accent grave fonctionne pour échapper aux guillemets doubles sur ce Surface Pro Win 10.

>powershell.exe "echo la`"" >> test
>type test
la"

Voici les résultats que j'ai obtenus pour d'autres caractères permettant d'échapper à un guillemet double :

la\
la^
la
la~

L'utilisation d'un autre guillemet pour échapper à un guillemet ne donne aucun guillemet. Comme vous pouvez le voir, les caractères eux-mêmes ont été tapés, mais ils n'ont pas échappé aux guillemets doubles.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X