web-dev-qa-db-fra.com

Échappe les guillemets en paramètre

Sous Unix, je pouvais exécuter myscript '"test"' et je voudrais obtenir "test".

Sous Windows cmd je reçois 'test'.

Comment puis-je passer des guillemets doubles en tant que paramètre? J'aimerais savoir comment le faire manuellement à partir d'une fenêtre cmd afin de ne pas avoir à écrire un programme pour tester mon programme.

89
Bryan Field

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

Peut-être que vous pouvez essayer le personnage d'échappement ^ comme ça: myscript '^"test^"'?

19
mousio

Un autre moyen d'échapper aux guillemets (bien que ce ne soit probablement pas préférable), que j'ai trouvé utilisé à certains endroits, consiste à tilisez plusieurs guillemets. Dans le but de rendre le code des autres personnes lisible, je vais expliquer.

Voici un ensemble de règles de base:

  1. Lorsque les groupes ne sont pas entre guillemets, les espaces séparent les paramètres:
    program param1 param2 param 3 passera quatre paramètres à program.exe:
    param1, param2, param et 3.
  2. Un groupe entre guillemets doubles ignore les espaces en tant que séparateurs de valeurs lors de la transmission de paramètres à des programmes:
    program one two "three and more" passera trois paramètres à program.exe:
    one, two et three and more. Maintenant, expliquons une partie de la confusion:
  3. Les groupes de guillemets doubles qui apparaissent directement adjacents au texte qui n'est pas entouré de guillemets doubles se rejoignent en un 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 entre guillemets doubles puissent apparaître directement adjacents l'un de l'autre.
  4. Les guillemets doubles qui suivent directement les guillemets sont traités comme (ou font partie de) du texte brut et non enveloppé adjacent au groupe des guillemets, mais une seule double citation:
    "Tim says, ""Hi!""" _ agira comme un paramètre: Tim says, "Hi!"

Ainsi, il existe trois types différents de guillemets: les guillemets qui s'ouvrent, les guillemets qui se ferment et les citations qui agissent comme du texte brut.
Voici la ventilation de cette dernière ligne source de confusion:

 "ouvrir le groupe de guillemets doubles. 
 T à l'intérieur de" "s 
 i à l'intérieur" "s 
 m à l'intérieur" "s 
 à l'intérieur" "s - l’espace ne sépare pas 
 dans "" s 
 a dans "" s 
 y dans "" s 
 s dans "" s 
, dans "" s 
 dans "" s - l’espace ne sépare pas 
 "ferme le groupe entre guillemets doubles 
" la citation suit directement de plus près - agit comme un texte non enveloppé: " 
 H en dehors de "" s - est joint au groupe adjacent précédent 
 I en dehors de "" s - ... 
! à l'extérieur "" s - ... 
 "ouvrez le groupe de guillemets doubles 
" fermez le groupe de guillemets doubles 
 "la citation suit directement de plus près - agit comme un texte non enveloppé:" 

Ainsi, le texte joint effectivement quatre groupes de caractères (un avec rien cependant):
Tim says, Est le premier, enveloppé pour échapper aux espaces
"Hi! est le second, non enveloppé (il n'y a pas d'espaces)
Est le troisième, un groupe de guillemets ne contenant rien
" est la quatrième, la citation proche non emballée.

Comme vous pouvez le constater, le groupe de guillemets doubles ne comportant toujours rien, il est toujours nécessaire, car sans lui, les guillemets suivants ouvriraient un groupe de guillemets doubles au lieu d’agir en tant que texte brut.

À partir de là, il convient de reconnaître que, par conséquent, les guillemets intérieurs et extérieurs, trois guillemets doubles agissent comme des guillemets doubles non échappés en texte brut:

 "Tim lui dit," "" Qu'est-ce qui se passe récemment? "" "" 

va imprimer 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 une évasion.
Cependant, en le comprenant, vous remarquerez que les quatre guillemets à la fin peuvent être réduits à deux, étant donné qu’il ajoute techniquement un autre groupe inutile inutile de doubles guillemets.

Voici quelques exemples pour le clore:

 programme ab REM envoie (a) et (b) 
 programme "" "a" "" REM envoie ( "a") 
 programme "" "ab" "" REM envoie ("a) et (b") 
 programme "" "" Bonjour, " "" Mike a dit. "REM envoie (" Bonjour, "a dit Mike.) 
 Programme" "a" "b" "c" "d" "REM envoie (abcd) puisque les groupes "" n'enveloppent rien 
 Programme "bonjour à" "" citations "" REM envoie (bonjour à "citations") 
 programme "" "" hello world "" REM envoie ("hello world") 
 programme "" "hello" world "" REM envoie ("bonjour le monde") 
 Programme "" "bonjour" le monde "" REM envoie ("bonjour) et (monde") 
 programme "bonjour" "monde" "" REM envoie (bonjour "monde") 
 programme "bonjour" "" monde "" REM = envoie (bonjour "monde") 

Note finale: je n'ai rien lu de cela dans aucun tutoriel - j'ai tout inventé en expérimentant. Par conséquent, mon explication peut ne pas être vraie en interne. Néanmoins, tous les exemples ci-dessus évaluent comme donné, validant ainsi (sans prouver) ma théorie.

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

178
Codesmith

Essaye ça:

myscript """test"""

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

22
smwikipedia

Le deuxième document cité par Peter Mortensen dans son commentaire sur la réponse de Codesmith m'a beaucoup éclairé. Ce document a été écrit par windowsinspired.com. Le lien répété: ne meilleure façon de comprendre comment citer et échapper des arguments de ligne de commande Windows .

Quelques essais et erreurs supplémentaires conduisent à la directive suivante:

Échapper à chaque citation double " avec un signe ^. Si vous voulez d'autres caractères ayant une signification particulière pour la commande Windows Shell (par exemple, <, >, |, &) à interpréter comme des caractères normaux à la place, puis échappez-les avec un signe aussi.

Si vous voulez que votre programme foo reçoive le texte en ligne de commande "a\"b c" > d et redirigez sa sortie vers le fichier out.txt, lancez votre programme comme suit à partir de la commande Windows Shell:

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

Si foo interprète \" comme une citation double littérale et attend des guillemets non espacés pour délimiter des arguments incluant des espaces, puis foo interprète la commande comme spécifiant un argument a"b c, un argument > et un argument d.

Si à la place foo interprète un guillemet double doublé "" comme une citation double littérale, puis démarrez votre programme en tant que

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

L’information clé du document cité est que, pour la commande Windows Shell, un guillemet double non échappé déclenche la commutation entre deux états possibles.

Quelques essais et erreurs supplémentaires impliquent que, dans l'état initial, la redirection (vers un fichier ou un canal) est reconnue et qu'un caret ^ échappe à une double citation et le curseur 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é. Appelons ces états "extérieur" et "intérieur", respectivement.

Si vous souhaitez rediriger la sortie de votre commande, la commande Shell doit être à l'état externe lorsqu'elle atteint la redirection. Il doit donc exister un nombre pair de guillemets doubles (par caret) précédant la redirection. foo "a\"b " > out.txt _ ne fonctionnera pas - la commande Shell transmet l'intégralité de "a\"b " > out.txt to foo en tant qu'arguments de ligne de commande combinés, au lieu de ne transmettre que "a\"b " et rediriger la sortie vers out.txt.

foo "a\^"b " > out.txt _ ne fonctionnera pas non plus, car le curseur ^ est rencontré à l’intérieur où il s’agit d’un caractère ordinaire et non d’un caractère d’échappement, donc "a\^"b " > out.txt est passé à foo.

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

Si vous n'avez pas besoin de redirection (ou d'autres caractères ayant une signification particulière pour la commande Shell), vous pouvez vous passer des carets. Si foo interprète \" comme une citation double littérale, vous pouvez l’appeler ainsi:

foo "a\"b c"

Alors foo reçoit "a\"b c" comme texte des arguments combinés et peut l’interpréter comme un seul argument égal à a"b c.

Maintenant - enfin - à la question initiale. myscript '"test"' appelé à partir de la commande Windows, Shell transmet '"test"' to myscript. Apparemment myscript interprète les guillemets simples et doubles comme des délimiteurs d'arguments et les supprime. Vous devez comprendre ce que myscript accepte comme une citation double littérale, puis spécifiez-le dans votre commande, en utilisant ^ pour échapper aux caractères ayant une signification particulière pour la commande Windows Shell. Étant donné que myscript est également disponible sous Unix, peut-être que \" fait le tour. Essayer

myscript \^"test\^"

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

myscript \"test\"
0
Louis Strous