web-dev-qa-db-fra.com

Gérer les citations dans les scripts batch Windows

Dans un fichier de commandes Windows, lorsque vous effectuez les opérations suivantes:

set myvar="c:\my music & videos"

la variable myvar est stockée avec les guillemets inclus. Honnêtement, je trouve cela très stupide. Les guillemets sont juste pour dire où la chaîne commence et se termine, pas pour être stockés dans le cadre de la valeur elle-même.
Comment puis-je empêcher que cela se produise?

Merci.

55
GetFree
set "myvar=c:\my music & videos"

Remarquez que les guillemets commencent avant myvar. C'est en fait aussi simple que cela. Note latérale: myvar ne peut pas être répercuté par la suite sauf s'il est entouré de guillemets car & sera lu comme un séparateur de commandes, mais cela fonctionnera toujours comme un chemin.

http://ss64.com/nt/set.html sous "Les noms de variables peuvent inclure des espaces"

50
RuskoGuyachev

C'est la bonne façon de procéder:

set "myvar=c:\my music & videos"

Les guillemets ne seront pas inclus dans la valeur de la variable.

60
Craig Rorrer

Cela dépend de la façon dont vous souhaitez utiliser la variable. Si vous souhaitez simplement utiliser la valeur de la variable sans les guillemets, vous pouvez utiliser soit une expansion retardée et une substitution de chaîne, soit la commande for:

@echo OFF
SETLOCAL enabledelayedexpansion

set myvar="C:\my music & videos"

Comme l'indique andynormancx, les guillemets sont nécessaires car la chaîne contient le &. Ou vous pouvez y échapper avec le ^, mais je pense que les citations sont un peu plus propres.

Si vous utilisez une expansion retardée avec substitution de chaîne, vous obtenez la valeur de la variable sans les guillemets:

@echo !myvar:"=!
>>> C:\my music & videos

Vous pouvez également utiliser la commande for:

for /f "tokens=* delims=" %%P in (%myvar%) do (
    @echo %%P
)
>>> C:\my music & videos

Cependant, si vous souhaitez utiliser la variable dans une commande, vous devez utiliser la valeur entre guillemets ou mettre la valeur de la variable entre guillemets:

  1. Utiliser la substitution de chaîne et l'expansion retardée pour utiliser la valeur de la variable sans guillemets, mais utilisez la variable dans une commande:

    @echo OFF
    SETLOCAL enabledelayedexpansion
    
    set myvar="C:\my music & videos"
    md %myvar%
    @echo !myvar:"=! created.
    
  2. Utilisation de la commande for pour utiliser la valeur de la variable sans guillemets, mais vous devrez entourer la variable de guillemets lors de son utilisation dans les commandes:

    @echo OFF
    set myvar="C:\my music & videos"
    
    for /f "tokens=* delims=" %%P in (%myvar%) do (
        md "%%P"
        @echo %%P created.
    )
    

Pour faire court, il n'y a vraiment aucun moyen propre d'utiliser un chemin ou un nom de fichier contenant des espaces intégrés et/ou &s dans un fichier batch.

35
Patrick Cuff

Utilisez jscript.

Il y a de nombreuses lunes (c'est-à-dire environ 8 ans de donner ou de prendre), je travaillais sur un grand projet C++/VB6, et j'avais plusieurs bits de script de lot pour faire des parties de la construction.

Ensuite, quelqu'un m'a pointé sur le Joel Test , j'étais particulièrement amoureux du point 2 et j'ai décidé de rassembler tous mes petits scripts de construction dans un seul script de construction. . .

et cela m'a presque brisé le cœur, en faisant travailler tous ces petits scripts ensemble, sur différentes machines, avec des configurations légèrement différentes, vous dieux, c'était horrible - en particulier le réglage des variables et le passage des paramètres. C'était vraiment fragile, la moindre chose le casserait et nécessiterait 30 minutes de peaufinage pour recommencer.

Finalement - je peux être têtu moi - J'ai jeté tout le lot et dans environ une journée réécrit tout en JavaScript , en l'exécutant à partir de l'invite de commande avec CScript.

Je n'ai pas regardé en arrière. Bien que ces jours-ci, ce soit MSBuild et Cruise Control, si je dois faire quelque chose, même légèrement, avec un script batch, j'utilise jscript.

6
Binary Worrier

L'interpréteur de commandes Windows vous permet d'utiliser les guillemets autour de la commande set entière (valable dans toutes les versions de Windows NT de NT 4.0 à Windows 2012 R2)

Votre script doit simplement être écrit comme suit:

@echo OFF

set "myvar=C:\my music & videos"

Ensuite, vous pouvez mettre des guillemets autour des variables selon vos besoins.

Travailler avec l'invite CMD peut parfois sembler ésotérique, mais l'interpréteur de commandes se comporte en fait assez solidement en obéissant à sa logique interne, il vous suffit de repenser les choses.

En fait, la commande set ne vous oblige pas du tout à utiliser des guillemets, mais à la fois la façon dont vous effectuez votre affectation de variable et la façon dont la méthode, sans guillemets, peut vous obliger à avoir des espaces supplémentaires autour de votre variable qui sont difficiles à remarquez lors du débogage de votre script.

par exemple. Les deux éléments ci-dessous sont techniquement valides, mais vous pouvez avoir des espaces de fin, ce n'est donc pas une bonne pratique:

set myvar=some text   
set myvar="some text" 

par exemple. Les deux méthodes ci-dessous sont de bonnes méthodes pour définir des variables dans l'interpréteur de commandes Windows, mais la méthode des guillemets doubles est supérieure:

set "myvar=Some text"
(set myvar=Some value)

Les deux ne laissent rien à l'interprétation de la variable aura exactement les données que vous recherchez.

texte fort Cependant, pour vos besoins, seule la méthode citée fonctionnera valablement car vous utilisez un caractère réservé

Ainsi, vous utiliseriez:

set myvar="c:\my music & videos"

Cependant, même si la variable IS est correctement définie sur cette chaîne, lorsque vous ECHO la piqûre, l'interpréteur de commandes interprète l'esperluette comme mot clé pour indiquer qu'une autre instruction suit.

Donc, si vous souhaitez faire écho à la chaîne de la variable, l'interpréteur CMD doit toujours être informé qu'il s'agit d'une chaîne de texte, ou si vous ne voulez pas que les guillemets indiquent que vous devez effectuer l'une des opérations suivantes:

faire écho à la variable WITH Quotes:

Echo."%myvar%"

faire écho à la variable SANS Citations:

Echo.%myvar:&=^&%
<nul SET /P="%myvar%"

Dans les deux scénarios ci-dessus, vous pouvez faire écho à la chaîne sans guillemets très bien. Exemple de sortie ci-dessous:

C:\Admin>    Echo.%myvar:&=^&%
C:\my music & videos

C:\Admin>    <nul SET /P="%myvar%"
C:\my music & videos
C:\Admin>
2
Ben Personick

Vous devez avoir les guillemets si le texte que vous définissez comprend certains caractères, y compris &. Si votre texte n'incluait pas & alors vous n'auriez pas besoin des guillemets.

Par exemple, si le texte était simplement "c:\ma musique", vous pourriez faire:

set myvar = c:\my music

Mais parce que votre texte a un & vous avez besoin des guillemets.

Modifier:

Ou, comme Dave le dit dans sa réponse, vous pouvez échapper aux caractères problématiques avec ^^^, mais méfiez-vous de cette approche car & n'est pas le seul caractère à échapper. En pratique, il est beaucoup plus facile de s'en tenir aux guillemets plutôt que d'échapper à tous les caractères problématiques.

1
andynormancx

Essayez d'utiliser le caractère d'échappement '^', par ex.

set myvar=c:\my music ^& videos

Vous devrez être prudent lorsque vous développez myvar car le shell peut ne pas traiter le & comme un littéral. Si ce qui précède ne fonctionne pas, essayez également d'insérer un curseur dans la chaîne:

set myvar=c:\my music ^^^& videos
1
Dave