バッチファイルではどのコメントスタイルを使用すればよいですか?


284

私はいくつかのバッチファイルを作成していて、このユーザーガイドに遭遇しました。それは私を示したことの一つは、ラインがでないだけで、コメントすることができますということでしたREMが、またして::。それは言う:

ラベルはリダイレクトシンボルの前に処理されるため、REMコマンドを使用するよりも、ダブルコードを使用してバッチコード内のコメントを作成できます。::<remark>問題はありませんがrem <remark>、エラーが発生します。

では、なぜ私が目にするほとんどのガイドと例でこのREMコマンドを使用するのですか?い::のWindowsのすべてのバージョンで仕事を?


3
「REM」は、Windowsの98の下にリダイレクトして行コメントアウトするために使用されたときにだけ、レコードのために、私は問題を見てきました
ディガー

6
余談ですが、@ Diggerのコメントに沿って:リンクされたガイドはDOScommand.exe)用でありcmd.exe、Windows 2000以降で見られるNTコマンドプロセッサ用ではありません。rem <remark>後者(少なくとも Windows XP以降)ではREM問題なく機能し、公式の制約であり、全体として最も安全な選択肢です。しばらくは、::その利点を持っている、それが最終的に問題のある内部のあるハックである(…)ブロック(ここでは、多くの回答で述べたように)。
mklement0 2017


1
では、REMでどのような状況でエラーが発生するのでしょうか。
TS

回答:


360

tl; dr: REMは、バッチファイルにコメントを埋め込むための文書化およびサポートされている方法です。


::本質的にはジャンプできない空白のラベルですREMが、実際には何もしないコマンドです。どちらの場合も(少なくともWindows 7では)、リダイレクトオペレーターが存在すると問題が発生します。

ただし、::特定の状況下では、ブロックとして正しく動作せず、ラベルとしてではなく、ある種のドライブ文字として解析されることがわかっています。私は正確にはどこにあるのか少し曖昧ですが、それだけで十分にREM独占的に使用できます。これはドキュメント化され、サポートされている方法であり、バッチファイルにコメントを埋め込むことができます::が、特定の実装の成果物にすぎません。


ループで::問題が発生する例を次に示しFORます。

この例は、デスクトップで呼び出されたファイルで機能しませんtest.bat

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

この例はコメントとして正しく機能しますが、

@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

問題は、出力をファイルにリダイレクトしようとしたときに発生するようです。私の推測では、それは::と呼ばれるエスケープされたラベルとして解釈されてい:echoます。


1
@Firedan:バッチファイルの名前とその場所は関連していますか(リダイレクト先のファイルの名前と場所とともに)。それ以外の場合は、例を簡略化するとよいでしょう。
Joey

15
tl; drを追加する素敵なタッチ
makoshichi 2016年

2
変数の使用が遅れている場合、::は特定のディスクドライバーが見つからないなどのエラーメッセージを表示します。
Scott Chu

2
::コメントが解析され、> |などの特殊文字 コメントを終了し、次のテキストはコメントされません。
mosh 2016

4
@moshは正しいです。たとえば、%VAR%変数が展開されます。あなたは(誤って)があるとしset TARGET=C:\Program Files (x86)\"foo.exe"、かつ内部でDO(..)表現あなたが持っている:: echo %TARGET%ので、あなたがエラーになります(x86)拡大します前に、式全体が評価されます無効につながる、DO(..)表現と非常にこのケースで不可解なエラー(「\ Microsoftは、この時点で予想外でした")。あなたも必要ありません|か、>あなたの表現インチ ただし::、A は実際のコメントでREMはありません。
アベル

161

REMへのコメント

A REMは、完全な行と、最初のトークンの終わりでない場合は行末にある複数行のキャレットをリマークできます。

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の後にいくつかの文字が続く.:\/=と、動作が少し異なります。アンパサンドはコメントされないため、インラインコメントとして使用できます。

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

ただしREMREM.batなどの既存のファイルの問題を回避するにはREM;.bat、変更したバリアントのみを使用する必要があります。

REM^;<space>Comment

そして、キャラクター;も許可されています;,:\/=

REMはおよそある6倍遅くより::(100000コメント行でWin7SP1でテスト)。
通常の使用では重要ではありません(コメント行あたり58µs対360µs)

::でのコメント

Aは::常に行末キャレットを実行します。

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

ラベルとコメントラベルに ::は、括弧ブロック内に特別なロジックがあります。
それらは常に2行にまたがっています。SO:gotoコマンドが機能していません
したがって、構文エラーの原因となることが多いため、括弧ブロックには推奨されません。

ライン示されているが、ない行はコメントでECHO ONREM::

どちらも実際には残りの行をコメントアウトすることはできないため、単純な%~コードでは構文エラーが発生します。

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

ただし、REMは、特殊文字フェーズが完了する前であっても、早い段階でバッチパーサーを停止できます。

@echo ON
REM This caret ^ is visible

&REMまたは&::を使用して、コマンドラインの最後にコメントを追加できます。「&」が同じ行に新しいコマンドを導入するため、このアプローチは機能します。

パーセント記号付きのコメント%=コメント=%

パーセント記号付きのコメントスタイルが存在します。

実際にはこれらは変数ですが、何も拡張されていません。
しかし、利点は、がなくても同じ行に配置できること&です。
等号は、そのような変数が存在できないことを保証します。

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

パーセントスタイルは、マクロが定義されるとコメントが削除されるため、実行時の動作を変更しないため、バッチマクロに推奨されます。

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

2
ことに留意すべきである%=コメントが引用符、すなわちと気難しいているset foo=bar %=baz中で結果fooに拡大しbar %=bazないよう、set foo="bar" %=baz唯一のに対し、set "foo=bar" %=baz中に結果fooに拡大bar意図したとおり。
LastStar007 2015

3
@ LastStar007:set "foo=bar"値を明確に区切る最も堅牢なフォームであるため、常に引用スタイルを使用することは、一般的に推奨する価値があります。あなたがしている記述の問題が内在しているset行動ではなく、固有の%= … =%コメント:あなたが使用しない限り"var=val"引用し、set次のすべてのものとみなし=、末尾の行の終わりまでの空白(または、該当する場合、開始を含めた値を、次のインラインコマンド)。
mklement0 2017

28

別の選択肢は、コメントを常に何にも展開しない変数展開として表現することです。

およびなどの=文書化されていない動的変数を除き、変数名にを含めることはできません。変数名に1番目の位置の後を含めることはできません。したがって、括弧で囲まれたブロック内にコメントを含めるために、以下を使用することがあります。
%=ExitCode%%=C:%=

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

インラインコメントを組み込むための良い方法でもあります

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

リーディング=は必要ありませんが、対称性の場合は好きです。

2つの制限があります。

1)コメントに含めることはできません %

2)コメントに含めることはできません :


笑!1つの特大の変数にしてください!天才!%=ExitCode%?きちんと。毎日新しいことを学びましょう!
James K

トレーリング=が必要であることを意味します。しかし、そうではないようです。
James K

4
@JamesK-末尾を使用して、=%= ExitCode =%のようなものが動的な変数ではなく「コメント」になるようにします。私は常に機能するスタイルを使用することを好みます(もちろん、回答の下部に記載されている制限を除きます)。
dbenham 2012

動的変数の詳細については、stackoverflow.com / a / 20169219/1689714(例:%= ExitCode%%= ExitCodeAscii%%= C:%%= D:%%__ CD __%など)、それらの意味、方法等が設定されます
。–キーロンハーディ2018

25

label ::を使用してコメントを作成したり、コードをコメントアウトしたりできることに気付いた後、私にはREM見苦しく見えました。前述のように、()ブロックされたコード内で使用するとダブルコロンが問題を引き起こす可能性がありますが、ラベル::とラベルを交互に使用することで回避策を発見しました:space

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

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

これは醜いものREMではなく、実際にコードに小さなスタイルを追加します。

したがって、使用するコードブロックの外側::と内側では、::とを交互に使用しています:

ちなみに、バッチファイルのヘッダーなど、大量のコメントの場合はgoto、コメントの上に重ねるだけで、特別なコマンドや文字を完全に回避できます。これにより、CMDこれらの行を実際に処理しようとするとヒスノイズが発生するという事実にもかかわらず、任意のメソッドまたはスタイルのマークアップを使用できます。

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

使用あなたが望む今まで表記*さん、@さんなど


/?このメニューを印刷するようにスイッチをどのように処理しますか?
hoang

1
@hoang setlocal ENABLEDELAYEDEXPANSION <NEWLINE> set var =%〜1 <NEWLINE> echo first param is%1 <NEWLINE> IF!VAR!== "/?" (GOTO USAGE)<NEWLINE>:USAGE <NEWLINE> echo blah blah .. <NEWLINE>
GL2014

16
行を挿入または削除する場合、シングルコロンとダブルコロンを交互に使用すると頭痛の種になるはずです。

@ GL2014は基本的に「このメニューを印刷しない」と言ってます。サンプルコードでは、使用上の注意の各行の前にエコーを付ける必要があります。ジェームズKの回答は、使用法のメモを記載どおりに印刷する方法があることを示唆しているため、誤解を招く可能性があります。
Timbo 2018

1
@Timbo私はこの回答の:PrintHelpためにサブルーチン()を書きました。それは確かに@hoangが要求することを実行します。私はマーカーとして<HELP>と</ HELP>を使用していますが、あなたの好きなものを使うことができます。
cdlvcdlv

21

この回答は、このページの多くの素晴らしい回答の実際的な要約を試みています。

jebの優れた答えは特別な言及に値します。なぜなら、それは本当に詳細であり、多くのエッジケースをカバーしているからです。
特に、変数やパラメーターの参照が正しく構成さ%~REMれてないと、次のようなソリューション(を含む)が壊れる可能性があると指摘しています


全行コメント-直接サポートされる唯一のスタイル:

  • REM(またはそのバリエーション)が唯一の公式コメント構成であり、最も安全な選択です-Joeyの役立つ回答を参照してください。

  • ::(広く使用されている)ハックであり、長所と短所があります。

    • 長所

    • 短所

      • (...)ブロックの内部で::は、コマンドを壊す可能性があり、安全な使用ルールは制限されており、覚えるのは容易ではありません -以下を参照してください。

あなたがいる場合使用したい::、あなたはこれらの選択肢があります。

  • どちらか:安全のため、内部例外作る(...)ブロックを使用し、REMそこに、または場所のコメントはない内部 (...)まったく。
  • または:次のスニペットに要約されている::Inside を安全に使用するための(...)非常に制限の厳しいルールを覚えてください。
@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.
)

他のコメントスタイルのエミュレーション -インラインおよびマルチライン:

これらのスタイルはいずれもバッチ言語直接サポートされてませんがエミュレートできます。


インラインコメント

*以下のコードスニペットverは、実験を容易にするために、任意のコマンドの代用として使用します。
* SETコマンドをインラインコメントで正しく機能させるには、name=valueパーツを二重引用符で囲みます。例えば、SET "foo=bar"[1]

このコンテキストでは、2つのサブタイプを区別できます。

  • EOLコメント([to-the-] end-of-line)。これはコマンドの後に置くことができ、常に行末まで拡張できます(ここでも、jebの回答厚意による):

    • ver & REM <comment>これはREM有効なコマンドであり&、既存のコマンドの後に追加のコマンドを配置するために使用できるという事実を利用しています。
    • ver & :: <comment>も動作しますが、実際には(...)ブロックの外でのみ使用できます。これは、その安全な使用が::スタンドアロンの使用よりもさらに制限されるためです。
  • 行内コメント行内の複数のコマンドのに、または理想的には特定のコマンドの内部にでも配置できます。
    行内コメントは最も柔軟な(単一行)フォームであり、定義によりEOLコメントとしても使用できます。

    • ver & REM^. ^<comment^> & verコマンドの間にコメントを挿入できます(ここでも、jebの回答によります)が、次の文字があるためエスケープする方法<とエスケープする>必要があることに注意してくださいそのままでは使用できません(エスケープされていない、または次のコマンドを開始する)。^< > |&&&||

    • %= <comment> =%dbenhamの素晴らしい答えで詳述されているようにれているように、(引数の中で)コマンドに配置できるため、最も柔軟な形式です。 これは、式は常にに展開することを確実な方法で可変の拡張構文を利用して、空の文字列 - 長いコメントのテキストはどちらも含まれていないようとして 同様に、十分に外側と内側の両方に機能ブロックを、それは、より視覚的に独特です。唯一の欠点は、タイプするのが難しく、構文的に誤解しやすく、広く知られていないことです。そのため、この手法を使用するソースコードの理解が妨げられる可能性があります。
      %:
      REM%= <comment> =%(...)


複数行(行全体のブロック)のコメント

  • James Kの答えは、gotoステートメントとラベルを使用して、任意の長さと内容の複数行コメントを区切る方法を示しています(彼の場合、使用情報を格納するために使用しています)。

  • Zeeの回答は、「ヌルラベル」を使用して複数行コメントを作成する方法を示していますが、すべての内部行をで終了するように注意する必要があります^

  • Rob van der Woudeのブログ投稿あなたがすることができます別の、ややあいまいなオプション言及終わるコメント行の任意の数のファイルを開口部が(のみ無視することが後に来るすべての原因であれば(非が含まれていないとして、^-escaped))、つまり、ブロックが閉じられていない限り


[1]を使用SET "foo=bar"して変数を定義すること、つまり、名前と=値を組み合わせて二重引用符を付けるSET "foo=bar" & REM Set foo to bar.こと、目的の変数値(この場合は次のコマンドまで)の後に続くことを確実にするためになどのコマンドで必要です。 1つのスペース)が誤ってその一部になることはありません。
(余談ですSET foo="bar"が、問題を回避するだけでなく、二重引用符を作成します値の一部にします)。
この問題は固有でSETあり、値に続く偶発的な末尾の空白にも当てはまるため常にこのSET "foo=bar"アプローチを使用することをお勧めします。


7

このページは、「::」を使用すると、特定の制約の下ではより高速になることを示しています。


2
これは真実であり、少なくともWin7SP1の場合::は6倍速くなる可能性がありますREM
jeb

4

良い質問です...私もこの機能をずっと探していました...

いくつかのテストとトリックの後、より良い解決策はより明白なものであるようです...

->パーサーの整合性の失敗を防止するために私が見つけた最善の方法は、REMを再利用することです。

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

"NULL LABEL"トリックで複数行を使用することもできます...(連続性のために行末の^を忘れないでください)

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

3

ジェームズK、私が言ったことのかなりの部分が間違っていてすみません。私が行ったテストは次のとおりです:

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

これは交互の説明を満たしていますが、「)は現時点では予期されていませんでした。エラーメッセージ。

今日はさらにテストを行ったところ、交互にすることが重要ではないことがわかりましたが、キーには偶数の行があり、2つの行が2つのコロン(::)で始まり、2つのコロンで終わっていないことがわかります。 。以下を検討してください。

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

これでうまくいきます!

しかしこれも考慮してください:

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

コマンドが終了するとき、偶数のコメントを持つというルールは適用されないようです。

残念ながら、これは十分にぎこちないので、使用したいかどうかはわかりません。

本当に、最良の解決策であり、私が考えることができる最も安全な解決策は、Notepad ++のようなプログラムがREMをダブルコロンとして読み取り、ファイルが保存されるときにREMステートメントとしてダブルコロンを書き戻すことです。しかし、私はそのようなプログラムを知らないし、それを行うNotepad ++のプラグインも知らない。


2

トピックに関する非常に詳細で分析的な議論は、このページで利用できます

サンプルコードとさまざまなオプションの長所/短所があります。


1
回答で提供されるリンクの内容を要約する必要があります。それ以外の場合は「リンクのみの回答」と呼ばれ、リンクが消えた場合はまったく役に立ちません。この場合、指摘されているページは、遅いフロッピーディスクからのバッチファイルの読み取り速度を最適化することに基づいて選択するという点で、かなりユーモラスです:)
GreenAsJade

0

バッチファイルでコメントするには、いくつかの方法があります。

1)remの使用

これが正式な方法です。::キャレットが処理される前に、解析が早く停止するようですが、実行に明らかに時間がかかります。パーセント拡張はremの前に行わ::れ、識別されるため、パーセントの使用が正しくない%~場合、つまりパーセントが存在する場合はエラーが発生します。コードブロックのどこでも安全に使用できます。

2)ラベルの使用 :::または:;

の場合:: comment、「:コメント」は無効な文字で始まるため、無効なラベル名です。ただし、ラベルの中央にコロンを使用してもかまいません。ラベルの先頭からスペースが始まる場合、は削除されてに: labelなり:labelます。ラベルの中央にスペースまたはコロンが表示される場合、名前の残りの部分は解釈されません。つまり、2つのラベル:f:ooとがある場合:f rr、両方が解釈:fされ、ファイル内で後で定義されたラベルのみにジャンプします。ラベルの残りの部分は実質的にコメントです。に代わる方法がいくつかありますここ::にリストします。あなたは決してできgotoまたはcallA::fooラベル。goto :fooそしてgoto ::fooません。

これらはコードブロックの外でも問題なく機能しますが、コードブロックのラベルの後に、無効かどうかにかかわらず、有効なコマンドラインが必要です。:: comment確かに別の有効なコマンドです。ラベルではなくコマンドとして解釈します。コマンドが優先されます。これは、::ボリュームにcdするコマンドです。これは、実行subst :: C:\した場合に機能します。それ以外の場合は、ボリュームエラーが見つかりません。これ:;は、このように解釈することができず、代わりにラベルとして解釈され、有効なコマンドとして機能するため、間違いなく優れている理由です。これは再帰的ではありません。つまり、次のラベルはその後にコマンドを必要としません。それが二人で来る理由です。

ラベルの後に有効なコマンドを入力する必要があります。 echo something。コードブロック内のラベルには少なくとも1つの有効なコマンドが含まれている必要があるため、行は2つのペアで構成されます。)次の行にスペースまたは閉じ括弧があると、予期しないエラーが発生します。2 ::行の間にスペースがあると、無効な構文エラーが発生します。

次の::ようにコメントでキャレット演算子を使用することもできます:

@echo off

echo hello
(
   :;(^
   this^
   is^
   a^
   comment^
   )
   :;
)
   :;^
   this^
   is^
   a^
   comment
   :;
) 

ただし、:;上記の理由により、末尾が必要です。

@echo off

(
echo hello
:;
:; comment
:; comment
:;
)
echo hello

偶数であれば結構です。これは間違いなくコメントするための最良の方法:;です-4行と。では:;2> nulまたはを使用して抑制する必要のあるエラーは発生しませんsubst :: C:\。あなたは使うことができますsubst :: C:\、ボリュームが見つからないというエラーが離れて行く作るためにそれはあなたがまた、Cを配置する必要があります意味:コードになってきてから作業ディレクトリを防ぐために::\

行の終わりにコメントするには、command &::またはを使用できますが command & rem comment、次のように偶数にする必要があります。

@echo off

(
echo hello & :;yes
echo hello & :;yes
:;
)

echo hello

最初のecho hello & :;yes行には次の行に有効なコマンドがありますが、2番目の行には& :;yesはないため、1つ、つまりが必要:;です。

3)無効な環境変数を使用する

%= comment =%。バッチファイルでは、定義されていない環境変数はスクリプトから削除されます。これにより、を使用せずに行末で使用でき&ます。無効な環境変数、つまり等号を含む環境変数を使用するのは慣習です。追加のequalsは必須ではありませんが、対称的に見えます。また、「=」で始まる変数名は、文書化されていない動的変数用に予約されています。これらの動的変数は「=」で終わることはないため、コメントの開始と終了の両方で「=」を使用することで、名前が衝突する可能性はありません。コメントに%またはを含めることはできません:

@echo off 
echo This is an example of an %= Inline Comment =% in the middle of a line.

4)コマンドとして、stderrをnulにリダイレクトする

@echo off
(
echo hello
;this is a comment 2> nul
;this is another comment  2> nul
)

5)ファイルの終わりにある、閉じられていない括弧の後のすべてがコメントです

@echo off
(
echo hello
)

(this is a comment
this is a comment
this is a comment
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.