it-swarm.com.de

Welchen Kommentarstil soll ich in Batch-Dateien verwenden?

Ich habe einige Batch-Dateien geschrieben und bin auf diese Bedienungsanleitung gestoßen, was sehr informativ war. Eine Sache, die mir gezeigt hat, war, dass Zeilen nicht nur mit REM, sondern auch mit :: kommentiert werden können. Es sagt:

Kommentare im Batchcode können mit einem Doppelpunkt gemacht werden. Dies ist besser als die Verwendung des Befehls REM, da Beschriftungen vor Umleitungssymbolen verarbeitet werden. ::<remark> verursacht keine Probleme, aber rem <remark> erzeugt Fehler.

Warum verwenden dann die meisten Anleitungen und Beispiele, die ich sehe, den Befehl REM? Funktioniert :: unter allen Windows-Versionen?

263
MikeFHay

tl; dr:REM ist die dokumentierte und unterstützte Methode zum Einbetten von Kommentaren in Stapeldateien.


:: ist im Wesentlichen ein leeres Etikett, zu dem niemals gesprungen werden kann, während REM ein tatsächlicher Befehl ist, der einfach nichts tut. In keinem Fall (zumindest unter Windows 7) verursacht das Vorhandensein von Umleitungsoperatoren ein Problem.

Es ist jedoch bekannt, dass sich :: unter bestimmten Umständen in Blöcken schlecht verhält und nicht als Etikett, sondern als eine Art Laufwerksbuchstabe analysiert wird. Ich bin ein wenig verwirrt, wo genau, aber das allein ist genug, um mich dazu zu bringen, ausschließlich REM zu verwenden. Dies ist die dokumentierte und unterstützte Methode zum Einbetten von Kommentaren in Stapeldateien, während :: lediglich ein Artefakt einer bestimmten Implementierung ist.


Hier ist ein Beispiel, in dem :: ein Problem in einer FOR -Schleife erzeugt.

Dieses Beispiel funktioniert in einer Datei mit dem Namen test.bat auf Ihrem Desktop nicht :

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

Während dieses Beispiel als Kommentar korrekt funktioniert:

@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

Das Problem scheint zu sein, wenn versucht wird, die Ausgabe in eine Datei umzuleiten. Ich gehe davon aus, dass es :: als Escape-Label namens :echo interpretiert.

336
Joey

Kommentare mit REM

Ein REM kann eine komplette Zeile markieren, auch ein mehrzeiliges Caret am Zeilenende, wenn es nicht das Ende des ersten Tokens ist.

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 gefolgt von einigen Zeichen .:\/= funktioniert etwas anders. Es wird kein kaufmännisches Und-Zeichen kommentiert, sodass Sie es als Inline-Kommentar verwenden können.

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

Um jedoch Probleme mit vorhandenen Dateien wie REM, REM.bat oder REM;.bat zu vermeiden, sollte nur eine geänderte Variante verwendet werden.

REM^;<space>Comment

Und für den Charakter ; ist auch einer von ;,:\/= erlaubt

REM ist ungefähr 6-mal langsamer als :: (getestet auf Win7SP1 mit 100000 Kommentarzeilen).
Für eine normale Verwendung ist es nicht wichtig (58µs gegenüber 360µs pro Kommentarzeile)

Kommentare mit ::

Ein :: führt immer ein Zeilenende-Caret aus .

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

Labels und auch das Kommentar-Label :: haben eine spezielle Logik in Klammerblöcken.
Sie überspannen immer zwei Zeilen SO: goto Befehl funktioniert nicht .
Sie werden daher nicht für Klammerblöcke empfohlen, da sie häufig die Ursache für Syntaxfehler sind.

Mit ECHO ON wird eine REM Zeile angezeigt, jedoch keine mit :: kommentierte Zeile

Beide können den Rest der Zeile nicht wirklich auskommentieren, sodass ein einfacher %~ einen Syntaxfehler verursacht.

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

Aber REM kann den Batch-Parser in einer frühen Phase stoppen, noch bevor die Sonderzeichenphase abgeschlossen ist.

@echo ON
REM This caret ^ is visible

Sie können & REM oder & :: verwenden, um am Ende der Befehlszeile einen Kommentar hinzuzufügen. Dieser Ansatz funktioniert, weil '&' einen neuen Befehl in derselben Zeile einführt.

Kommentare mit Prozentzeichen% = comment =%

Es gibt einen Kommentarstil mit Prozentzeichen.

In Wirklichkeit sind dies Variablen, aber sie werden zu nichts erweitert.
Aber der Vorteil ist, dass sie auch ohne & in dieselbe Zeile gesetzt werden können.
Das Gleichheitszeichen stellt sicher, dass eine solche Variable nicht existieren kann.

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

Der Prozentstil wird für Batch-Makros empfohlen, da er das Laufzeitverhalten nicht ändert, da der Kommentar beim Definieren des Makros entfernt wird.

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

Eine andere Alternative besteht darin, den Kommentar als variable Erweiterung auszudrücken, die sich immer zu nichts erweitert.

Variablennamen dürfen nicht = enthalten, außer für undokumentierte dynamische Variablen wie
%=ExitCode% und %=C:%. Kein Variablenname darf jemals einen = nach der ersten Position enthalten. Daher benutze ich manchmal Folgendes, um Kommentare in einen Block in Klammern einzufügen:

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

Es ist auch eine gute Methode zum Einfügen von Inline-Kommentaren

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

Der führende = ist nicht notwendig, aber ich mag wenn für die Symmetrie.

Es gibt zwei Einschränkungen:

1) Der Kommentar darf nicht % enthalten

2) Der Kommentar darf nicht : enthalten

27
dbenham

Nachdem mir klar wurde, dass ich mit dem Label :: Kommentare schreiben und Code auskommentieren kann REM sah für mich einfach hässlich aus. Wie bereits erwähnt, kann der Doppelpunkt Probleme verursachen, wenn er in () blockiertem Code verwendet wird. Ich habe jedoch eine Problemumgehung entdeckt, indem ich zwischen den Bezeichnungen :: und : gewechselt habe.space

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

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

Es ist nicht hässlich wie REM und fügt Ihrem Code tatsächlich einen kleinen Stil hinzu.

Außerhalb von Codeblöcken verwende ich :: und innerhalb von ihnen wechsle ich zwischen :: und :.

Übrigens können Sie bei vielen Kommentaren, wie im Header Ihrer Batch-Datei, spezielle Befehle und Zeichen vollständig vermeiden, indem Sie einfach goto über Ihre Kommentare gehen. Auf diese Weise können Sie eine beliebige Methode oder einen beliebigen Markup-Stil verwenden, auch wenn CMD jemals versucht hat, diese Zeilen tatsächlich zu verarbeiten, würde dies ein Rauschen hervorrufen.

@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
.
.
.

Verwenden Sie die gewünschte Schreibweise für *, @ usw.

25
James K

Diese Antwort versucht eine pragmatische Zusammenfassung der vielen großartigen Antworten auf dieser Seite:

Jebs großartige Antwort verdient besondere Erwähnung, weil es wirklich ausführlich ist und viele Edge-Fälle abdeckt.
Insbesondere weist er darauf hin, dass eine falsch konstruierte Variablen-/Parameterreferenz wie %~beliebige der folgenden Lösungen unterbrechen kann - einschließlich REM Zeilen .


Ganze Zeile Kommentare - der einzige direkt unterstützte Stil:

  • REM (oder Variationen davon) ist das einzige offizielle Kommentarkonstrukt , und ist die sicherste Wahl - siehe Joeys hilfreiche Antwort .

  • :: ist ein (weit verbreiteter) Hack, der Profis hat und Nachteile :

    • Vorteile :

    • Nachteile :

      • In (...) Blöcken kann ::break den Befehl und den Regeln für die sichere Verwendung sind restriktiv und nicht leicht zu merken - siehe unten.

Wenn Sie do:: verwenden möchten, haben Sie folgende Möglichkeiten:

  • Entweder: Um sicher zu gehen, machen Sie eine Ausnahme in (...) -Blöcken und verwenden Sie dort REM, oder platzieren Sie keine Kommentare inside(...) insgesamt.
  • Oder: Merken Sie sich die schmerzhaft einschränkenden Regeln für die sichere Verwendung von :: in (...) In folgendem Ausschnitt zusammengefasst:
@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 von anderen Kommentarstilen - Inline und Multi-Line:

Beachten Sie, dass keiner dieser Stile direkt von der Batch-Sprache unterstützt wird, aber emuliert ​​sein kann.


Inline-Kommentare :

* Die folgenden Codeausschnitte verwenden ver als Ersatz für einen beliebigen Befehl, um das Experimentieren zu erleichtern.
* Um sicherzustellen, dass SET-Befehle mit Inline-Kommentaren korrekt funktionieren, setzen Sie den Teil name=value in doppelte Anführungszeichen. z.B. SET "foo=bar".[1]

In diesem Zusammenhang können wir zwei Untertypen unterscheiden:

  • EOL-Kommentare ([bis zum Zeilenende]), die nach einem Befehl eingefügt werden können und sich immer bis zum Ende des Befehls erstrecken line (wieder mit freundlicher Genehmigung von Jebs Antwort ):

    • ver & REM <comment> nutzt die Tatsache, dass REM ein gültiger Befehl ist und & verwendet werden kann, um einen zusätzlichen Befehl nach einem vorhandenen zu platzieren.
    • ver & :: <comment> funktioniert auch, ist aber wirklich nur außerhalb von (...) -Blöcken verwendbar, da die sichere Verwendung dort noch eingeschränkter ist als bei der Verwendung von :: Standalone.
  • Zeileninterne Kommentare , die zwischen mehreren Befehlen in einer Zeile oder idealerweise sogar innerhalb stehen eines gegebenen Befehls.
    Intra-Line-Kommentare sind die flexibelste (einzeilige) Form und können per Definition auch als EOL-Kommentare verwendet werden.

    • ver & REM^. ^<comment^> & ver ermöglicht das Einfügen eines Kommentars zwischen Befehlen (ebenfalls mit freundlicher Genehmigung von Jebs Antwort ), aber beachten Sie, wie < und >^- entkommen mussten, weil die folgenden Zeichen. kann nicht verwendet werden, wie es ist: < > | (wohingegen ohne Flucht & oder && oder || das next starten = Befehl).

    • %= <comment> =%, wie in dbenhams großartige Antwort beschrieben, ist die flexibelste Form , weil es kann gesetzt werden inside ein Befehl (unter den Argumenten) .
      Es nutzt die Syntax der Variablenerweiterung auf eine Weise, die sicherstellt, dass der Ausdruck immer in die Zeichenfolge leere Zeichenfolge - erweitert wird, solange der Kommentartext vorhanden ist enthält weder % noch :
      Wie REM funktioniert %= <comment> =% sowohl außerhalb als auch innerhalb von (...) Blöcken gut, ist jedoch optisch ausgeprägter. Die einzigen Nachteile sind, dass es schwieriger ist zu tippen, syntaktisch leichter zu verwechseln und nicht allgemein bekannt ist, was das Verständnis des Quellcodes, der diese Technik verwendet, beeinträchtigen kann.


Mehrzeilige Kommentare :

  • James Ks Antwort zeigt, wie Sie mit einer goto-Anweisung und einem Label einen mehrzeiligen Kommentar beliebiger Länge und beliebigen Inhalts abgrenzen (die er in seinem Fall verwendet, um Nutzungsinformationen zu speichern).

  • Zees Antwort zeigt, wie ein "Null-Label" verwendet wird, um einen mehrzeiligen Kommentar zu erstellen, wobei Vorsicht geboten ist Beenden Sie alle inneren Zeilen mit ^.

  • Rob van der Woude's Blogpost erwähnt eine weitere etwas obskure Option, mit der Sie end eine Datei mit einer beliebigen Anzahl von Kommentarzeilen : Ein öffnende ( nur bewirkt, dass alles, was danach kommt, ignoriert wird , solange es kein (non -^- escaped) ) enthält, dh solange der Block nicht closed ist.


[1] Die Verwendung von SET "foo=bar" zum Definieren von Variablen - dh das Setzen von doppelten Anführungszeichen um den Namen und = und den Wert kombiniert ​​- ist in Befehlen wie SET "foo=bar" & REM Set foo to bar. erforderlich. , um sicherzustellen, dass das, was folgt ​​der beabsichtigte Variablenwert (bis zum nächsten Befehl, in diesem Fall ein einzelnes Leerzeichen) nicht versehentlich ein Teil davon wird.
(Nebenbei bemerkt: SET foo="bar" würde das Problem nicht nur nicht vermeiden, sondern auch doppelte Anführungszeichen Teil des Werts).
Beachten Sie, dass dieses Problem in SET inhärent ist und sogar auf accidental abschließende Leerzeichen nach dem Wert angewendet wird. Daher ist es ratsam, immer benutze den SET "foo=bar" Ansatz

19
mklement0

This page sagen, dass die Verwendung von "::" unter bestimmten Bedingungen schneller sein wird Nur eine Sache, die Sie bei der Auswahl berücksichtigen sollten

7
mishal153

gute frage ... ich habe auch lange nach dieser funktionalität gesucht ...

nach mehreren Tests und Tricks scheint die bessere Lösung die offensichtlichere zu sein ...

-> Der beste Weg, den ich gefunden habe, um zu verhindern, dass die Parser-Integrität versagt, ist die Wiederverwendung von REM:

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

sie können auch mehrere Zeilen mit dem Trick "NULL LABEL" verwenden. (Vergessen Sie nicht das ^ am Ende der Zeile, um die Kontinuität zu gewährleisten.)

::(^
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, es tut mir leid, dass ich mich in einem guten Teil von dem, was ich sagte, geirrt habe. Der Test, den ich gemacht habe, war der folgende:

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

Dies entspricht Ihrer Beschreibung des Alternierens, schlägt jedoch mit einem ") fehl, das zu diesem Zeitpunkt unerwartet war." Fehlermeldung.

Ich habe heute weitere Tests durchgeführt und festgestellt, dass Alternieren nicht der Schlüssel ist, aber es scheint, dass der Schlüssel eine gerade Anzahl von Zeilen hat, keine zwei Zeilen in einer Reihe, die mit einem Doppelpunkt (: :) beginnen und nicht mit einem Doppelpunkt enden . Folgendes berücksichtigen:

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

Das funktioniert!

Beachten Sie aber auch Folgendes:

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

Die Regel einer geraden Anzahl von Kommentaren scheint beim Beenden eines Befehls nicht zuzutreffen.

Leider ist das nur so eichhörnchenartig, dass ich nicht sicher bin, ob ich es verwenden möchte.

Die beste und sicherste Lösung, die ich mir vorstellen kann, ist, wenn ein Programm wie Notepad ++ REM als doppelte Doppelpunkte liest und dann doppelte Doppelpunkte als REM -Anweisungen zurückschreibt, wenn Die Datei wird gespeichert. Aber mir ist ein solches Programm nicht bekannt, und mir sind auch keine Plugins für Notepad ++ bekannt, die dies tun.

3
Darin

Eine sehr detaillierte und analytische Diskussion zu diesem Thema finden Sie auf der Seite THIS

Es hat die Beispielcodes und die Vor-/Nachteile verschiedener Optionen.

2
BiLaL