web-dev-qa-db-fra.com

Quel style de commentaire dois-je utiliser dans les fichiers de commandes?

J'ai écrit des fichiers de commandes et j'ai rencontré ce guide de l'utilisateur , qui a été assez instructif. Une chose m'a montré que les lignes peuvent être commentées non seulement avec REM, mais aussi avec ::. Ça dit:

Les commentaires dans le code de lot peuvent être faits en utilisant un double-virgule, ce qui est mieux que d'utiliser la commande REM, car les étiquettes sont traitées avant les symboles de redirection. ::<remark> ne pose aucun problème, mais rem <remark> génère des erreurs.

Pourquoi, alors, la plupart des guides et des exemples que je vois utilisent-ils la commande REM? Est-ce que :: fonctionne sur toutes les versions de Windows?

263
MikeFHay

tl; dr:REM est le moyen documenté et pris en charge d’incorporer des commentaires dans des fichiers de traitement par lots.


:: est essentiellement une étiquette vierge à laquelle on ne peut jamais accéder, alors que REM est une commande réelle qui ne fait rien. Dans aucun des deux cas (du moins sous Windows 7), la présence d'opérateurs de redirection ne pose problème.

Cependant, il est connu que :: se comporte mal en blocs dans certaines circonstances; il n'est pas analysé comme une étiquette, mais comme une sorte de lettre de lecteur. Je suis un peu flou sur où exactement mais cela seul est suffisant pour me faire utiliser REM exclusivement. C'est le moyen documenté et supporté d'incorporer des commentaires dans des fichiers batch alors que :: n'est qu'un artefact d'une implémentation particulière.


Voici un exemple où :: génère un problème dans une boucle FOR.

Cet exemple ne fonctionnera pas dans un fichier nommé test.bat sur votre bureau:

@echo off
for /F "delims=" %%A in ('type C:\Users\%username%\Desktop\test.bat') do (
    ::echo hello>C:\Users\%username%\Desktop\text.txt
)
pause

Bien que cet exemple fonctionne correctement comme commentaire:

@echo off
for /F "delims=" %%A in ('type C:\Users\%username%\Desktop\test.bat') do (
    REM echo hello>C:\Users\%username%\Desktop\text.txt
)
pause

Le problème semble être lorsque vous essayez de rediriger la sortie dans un fichier. Ma meilleure hypothèse est qu'il interprète :: comme une étiquette échappée appelée :echo.

336
Joey

Commentaires avec REM

Un REM peut remarquer une ligne complète, ainsi qu'un signe multiligne à la fin de la ligne, si ce n'est pas la fin du premier jeton.

REM This is a comment, the caret is ignored^
echo This line is printed

REM This_is_a_comment_the_caret_appends_the_next_line^
echo This line is part of the remark

REM suivi de quelques caractères .:\/= fonctionne un peu différemment, il ne commente pas une esperluette, vous pouvez donc l'utiliser comme commentaire en ligne.

echo First & REM. This is a comment & echo second

Mais pour éviter les problèmes avec les fichiers existants tels que REM, REM.bat ou REM;.bat, seule une variante modifiée doit être utilisée.

REM^;<space>Comment

Et pour le caractère ; est également autorisé l'un des ;,:\/=

REM est environ 6 fois plus lent que :: (testé sur Win7SP1 avec 100000 lignes de commentaire).
Pour une utilisation normale, ce n'est pas important (58µs contre 360µs par ligne de commentaire)

Commentaires avec ::

Un :: toujours exécute un caret de fin de ligne.

:: This is also a comment^
echo This line is also a comment

Les étiquettes ainsi que l'étiquette de commentaire :: ont une logique spéciale entre les blocs de parenthèses.
Ils couvrent toujours deux lignes SO: la commande goto ne fonctionne pas .
Ils ne sont donc pas recommandés pour les blocs de parenthèses, car ils sont souvent la cause d'erreurs de syntaxe.

Avec ECHO ON, une ligne REM est affichée, mais pas une ligne commentée avec ::.

Les deux ne peuvent pas vraiment commenter le reste de la ligne, donc un simple %~ provoquera une erreur de syntaxe.

REM This comment will result in an error %~ ...

Mais REM est capable d’arrêter l’analyseur de lot à un stade précoce, même avant la phase des caractères spéciaux.

@echo ON
REM This caret ^ is visible

Vous pouvez utiliser & REM ou & :: pour ajouter un commentaire à la fin de la ligne de commande. Cette approche fonctionne car '&' introduit une nouvelle commande sur la même ligne.

Commentaires avec signes de pourcentage% = comment =%

Il existe un style de commentaire avec des signes de pourcentage.

En réalité, ce sont des variables mais elles sont étendues à rien.
Mais l’avantage, c’est qu’ils peuvent être placés dans la même ligne, même sans &.
Le signe égal garantit qu'une telle variable ne peut pas exister.

echo Mytest
set "var=3"     %= This is a comment in the same line=%

Le style de pourcentage est recommandé pour les macros par lots, car il ne modifie pas le comportement d'exécution, car le commentaire sera supprimé lors de la définition de la macro.

set $test=(%\n%
%=Start of code=% ^
echo myMacro%\n%
)
153
jeb

Une autre alternative consiste à exprimer le commentaire sous la forme d'une extension variable qui s'étend toujours à néant.

Les noms de variables ne peuvent pas contenir =, sauf pour les variables dynamiques non documentées telles que
%=ExitCode% et %=C:%. Aucun nom de variable ne peut jamais contenir un = après la 1ère position. J'utilise donc parfois les éléments suivants pour inclure des commentaires dans un bloc entre parenthèses:

::This comment hack is not always safe within parentheses.
(
  %= This comment hack is always safe, even within parentheses =%
)

C'est aussi une bonne méthode pour incorporer des commentaires en ligne

dir junk >nul 2>&1 && %= If found =% echo found || %= else =% echo not found

Le = non significatif n'est pas nécessaire, mais j'aime bien si pour la symétrie.

Il y a deux restrictions:

1) le commentaire ne peut pas contenir %

2) le commentaire ne peut pas contenir :

27
dbenham

Après avoir réalisé que je pouvais utiliser l'étiquette :: pour faire des commentaires et commenter le code REM, cela me paraissait carrément moche. Comme cela a été mentionné, le double-colon peut causer des problèmes lorsqu'il est utilisé dans le code bloqué (), mais j'ai découvert une solution de contournement en alternant les étiquettes :: et :space

:: This, of course, does
:: not cause errors.

(
  :: But
   : neither
  :: does
   : this.
)

Ce n'est pas moche comme REM et ajoute un peu de style à votre code.

Donc, en dehors des blocs de code, j'utilise :: et à l'intérieur, je alterne entre :: et :.

En passant, pour les gros morceaux de commentaires, comme dans l'en-tête de votre fichier de commandes, vous pouvez éviter complètement les commandes et les caractères spéciaux en plaçant simplement gotoing au dessus de vos commentaires. Cela vous permet d'utiliser n'importe quelle méthode ou style de balisage de votre choix, malgré le fait que si CMD tentait réellement de traiter ces lignes, il aurait été très sifflant.

@echo off
goto :TopOfCode

=======================================================================
COOLCODE.BAT

Useage:
  COOLCODE [/?] | [ [/a][/c:[##][a][b][c]] INPUTFILE OUTPUTFILE ]

Switches:
       /?    - This menu
       /a    - Some option
       /c:## - Where ## is which line number to begin the processing at.
         :a  - Some optional method of processing
         :b  - A third option for processing
         :c  - A forth option
  INPUTFILE  - The file to process.
  OUTPUTFILE - Store results here.

 Notes:
   Bla bla bla.

:TopOfCode
CODE
.
.
.

Utilisez la notation de votre choix *, @ etc.

25
James K

Cette réponse tente un résumé pragmatique parmi les nombreuses bonnes réponses de cette page:

La réponse de jeb mérite une mention spéciale, car il va vraiment en profondeur et couvre de nombreux cas Edge.
Il souligne notamment que une variable/référence de paramètre mal interprétée telle que %~ peut rompre toute solution ci-dessous - y compris les lignes REM.


commentaires sur toute la ligne - seul style pris en charge directement:

  • REM (ou leurs variantes de casse) est le uniquement le commentaire officiel , et le choix le plus sûr - voir réponse utile de Joey .

  • :: est un hack (largement utilisé) , qui a pour et contre :

    • Pros :

    • Cons :

      • Inside (...) blocs, :: peut briser la commande , et le les règles d'utilisation sûre sont restrictives et difficiles à retenir - voir ci-dessous.

Si vous faites vous voulez utiliser ::, vous avez les choix suivants:

  • Soit : Pour plus de sécurité, créez une exception à l'intérieur de (...) blocs et utilisez REM ou ne placez pas de commentaires à l'intérieur de (...) tout à fait.
  • ou : mémorisez le règles extrêmement restrictives pour une utilisation sûre de :: à l'intérieur de (...), qui sont résumées dans l'extrait suivant:
@echo off

for %%i in ("dummy loop") do (

  :: This works: ONE comment line only, followed by a DIFFERENT, NONBLANK line.
  date /t

  REM If you followed a :: line directly with another one, the *2nd* one
  REM would generate a spurious "The system cannot find the drive specified."
  REM error message and potentially execute commands inside the comment.
  REM In the following - commented-out - example, file "out.txt" would be
  REM created (as an empty file), and the ECHO command would execute.
  REM   :: 1st line
  REM   :: 2nd line > out.txt & echo HERE

  REM NOTE: If :: were used in the 2 cases explained below, the FOR statement
  REM would *break altogether*, reporting:
  REM  1st case: "The syntax of the command is incorrect."
  REM  2nd case: ") was unexpected at this time."

  REM Because the next line is *blank*, :: would NOT work here.

  REM Because this is the *last line* in the block, :: would NOT work here.
)

Emulation de autres styles de commentaire - en ligne et multiligne:

Notez que aucun de ces styles n'est directement pris en charge par le langage de traitement par lots , mais peut être émulé .


Inline comments :

* Les extraits de code ci-dessous utilisent ver en tant que remplaçant d'une commande arbitraire, afin de faciliter l'expérimentation.
* Pour que les commandes SET fonctionnent correctement avec des commentaires en ligne, cochez la partie name=value; Par exemple, SET "foo=bar".[1]

Dans ce contexte, nous pouvons distinguer deux sous-types:

  • EOL comments (à la fin de la ligne), qui peut être placé après une commande et s'étend invariablement jusqu'à la fin de la ligne (à nouveau, avec la permission de réponse de jeb ):

    • ver & REM <comment> profite du fait que REM est une commande valide et que & peut être utilisé pour placer une commande supplémentaire après une commande existante.
    • ver & :: <comment> fonctionne aussi, mais est utilisable uniquement en dehors de (...) blocks , car son utilisation en toute sécurité est encore plus limitée que d'utiliser :: autonome.
  • Commentaires intra-lignes , qui doivent être placés entre plusieurs commandes sur une ligne ou idéalement même à l'intérieur d'une commande donnée.
    Les commentaires intra-lignes sont la forme la plus flexible (ligne unique) et peut par définition également être utilisé comme commentaire EOL.

    • ver & REM^. ^<comment^> & ver permet l'insertion d'un commentaire entre les commandes (à nouveau, grâce à réponse de jeb ) Notez toutefois que < et > doivent être ^- échappés, car les caractères suivants ne peuvent pas être utilisés tels quels: < > | (alors que & ou && ou || non échappé lance la commande suivante ).

    • %= <comment> =%, comme détaillé dans la réponse géniale de dbenham , est le forme la plus flexible , car il peut être placé à l'intérieur d'une commande (parmi les arguments) .
      Il tire parti de la syntaxe à expansion variable de manière à ce que l’expression soit toujours étendue à la chaîne vide - tant que le le texte du commentaire ne contient ni % ni :
      Comme REM, %= <comment> =% fonctionne bien à l'intérieur et à l'extérieur de (...) blocs, mais il est plus distinctif sur le plan visuel; Le seul inconvénient est qu'il est plus difficile de dactylographier, de se tromper syntaxiquement et d'être mal connu, ce qui peut nuire à la compréhension du code source qui utilise cette technique.


Commentaires sur plusieurs lignes (bloc de la ligne entière) :

  • La réponse de James K montre comment utiliser une instruction goto et une étiquette pour délimiter un commentaire multiligne de longueur et de contenu arbitraires (qu'il utilise pour stocker des informations d'utilisation).

  • La réponse de Zee montre comment utiliser un "étiquette nulle" pour créer un commentaire sur plusieurs lignes, bien qu'il faille prendre soin de terminer toutes les lignes intérieures avec ^.

  • Le post de blog de Rob van der Woude mentionne une autre option quelque peu obscure qui vous permet de ) mettre fin à un fichier avec un nombre arbitraire de lignes de commentaires : Un ouvrant ( seulement fait en sorte que tout ce qui vient après soit ignoré , aussi longtemps car il ne contient pas de (non -^- échappé) ), c'est-à-dire tant que le bloc n'est pas fermé .


[1] Utiliser SET "foo=bar" pour définir des variables, c'est-à-dire mettre des guillemets doubles autour du nom et de = et de la valeur combinée - est nécessaire dans les commandes telles que SET "foo=bar" & REM Set foo to bar., afin de s'assurer que ce que suit la valeur de variable voulue (jusqu'à la commande suivante, dans ce cas un seul espace) ne fait pas accidentellement partie de il.
(En passant: SET foo="bar" ne permettrait pas non seulement d'éviter le problème, il ferait des guillemets doubles une partie de la valeur ).
Notez que ce problème est inhérent à SET et s’applique même à les espaces de fuite accidentels suivant la valeur, donc il est conseillé de toujours utiliser l'approche SET "foo=bar".

19
mklement0

Cette page indique que l'utilisation de "::" sera plus rapide sous certaines contraintes. Juste une chose à considérer lors du choix

7
mishal153

bonne question ... Je cherche aussi cette fonctionnalité depuis longtemps ...

après plusieurs tests et astuces, il semble que la meilleure solution soit la plus évidente ...

-> La meilleure façon de le faire, en empêchant l’intégrité de l’analyseur, est de réutiliser REM:

echo this will show until the next REM &REM this will not show

vous pouvez aussi utiliser plusieurs lignes avec le truc "NULL LABEL" ... (n'oubliez pas le ^ en fin de ligne pour la continuité)

::(^
this is a multiline^
comment... inside a null label!^
dont forget the ^caret at the end-of-line^
to assure continuity of text^ 
)
4
ZEE

James K, je suis désolé, je me suis trompé dans une bonne partie de ce que j'ai dit. Le test que j'ai fait était le suivant:

@ECHO OFF
(
  :: But
   : neither
  :: does
   : this
  :: also.
)

Cela correspond à votre description de l’alternance mais échoue avec un ") était inattendu à ce moment-là." Message d'erreur.

J'ai fait quelques tests plus approfondis aujourd'hui et j'ai constaté que l'alternance n'était pas la clé mais il semble que la clé consiste en un nombre pair de lignes, sans deux lignes consécutives commençant par un double point-virgule (: :) et ne se terminant pas par un double point-virgule . Considérer ce qui suit:

@ECHO OFF
(
   : But
   : neither
   : does
   : this
   : cause
   : problems.
)

Cela marche!

Mais considérez aussi ceci:

@ECHO OFF
(
   : Test1
   : Test2
   : Test3
   : Test4
   : Test5
   ECHO.
)

La règle d'avoir un nombre pair de commentaires ne semble pas s'appliquer lors de la fin d'une commande.

Malheureusement, c'est assez insuffisant pour que je ne sois pas sûr de vouloir l'utiliser.

Vraiment, la meilleure solution, et la plus sûre que je puisse imaginer, est si un programme comme Notepad ++ lirait REM comme un double point-virgule, puis écrirait les doubles points-deux en tant que REM le fichier est enregistré. Mais je ne suis pas au courant d’un tel programme et d’aucun plug-in pour Notepad ++ qui le fait non plus.

3
Darin

Une discussion très détaillée et analytique sur le sujet est disponible à la page THIS

Il contient les exemples de codes et les avantages/inconvénients de différentes options.

2
BiLaL