web-dev-qa-db-ja.com

バッチファイルではどのコメントスタイルを使用する必要がありますか?

私はいくつかのバッチファイルを書いてきました、そして私は このユーザガイド に出会いました - これは非常に有益でした。それが私に示したことの1つは、行がREMだけでなく::でもコメントできることです。それは言います:

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

それでは、なぜ私が見るほとんどのガイドと例はREMコマンドを使うのですか? ::はすべてのバージョンのWindowsで動作しますか?

255
MikeFHay

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


::は基本的にジャンプできない空白のラベルですが、REMは実際には何もしないコマンドです。どちらの場合も(少なくともWindows 7では)リダイレクト演算子があっても問題は起こりません。

ただし、::は特定の状況下ではブロック単位で誤動作することが知られています。ラベルとしてではなく、ある種のドライブ文字として解析されます。私はどこで正確に曖昧ですが、それだけでREMを排他的に使用するのに十分です。 ::は単なる特定の実装の成果物であるのに対して、バッチファイルにコメントを埋め込むための文書化されサポートされている方法です。


これは::FORループで問題を起こす例です。

この例では、デスクトップ上のtest.batというファイルで not が動作します。

@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という名前のエスケープラベルとして解釈されているのではないでしょうか。

327
Joey

REMへのコメント

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

そして文字;には;,:\/=のうちの1つも許されます

REMは::よりも約 6倍遅くなります (Win7SP1でテストされたコメント行数100000)。
通常の使用法ではそれほど重要ではありません(1コメント行あたり58μs対360μs)

::でコメント

::は常に実行行末キャレットです。

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

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

ECHO ONではREM行が表示されますが、::でコメントされた行は表示されません

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

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

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

@echo ON
REM This caret ^ is visible

コマンドラインの末尾にコメントを追加するには、 &REMまたは&::を使用できます。 '&'は同じ行に新しいコマンドを導入するので、このアプローチはうまくいきます。

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

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

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

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

マクロの定義時にコメントは削除されるため、実行時の動作は変わりません。パーセントスタイルはバッチマクロに推奨されます。

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

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

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

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

REMname__のように醜いものではなく、実際にはコードに少しスタイルを追加します。

そのため、コードブロックの外側で::を使用し、その内側で:::を交互に使用します。

ちなみに、バッチファイルのヘッダーのように大量のコメントがある場合は、コメントの上にgotoname__を付けることで、特殊なコマンドや文字を完全に避けることができます。 CMDname__が実際にそれらの行を処理しようとした場合、それが厄介なことになるという事実にもかかわらず、これであなたはあなたが望むマークアップの任意の方法やスタイルを使いましょう。

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

*@などの表記法を使います。

25
James K

もう1つの選択肢は、コメントを常に0に展開される変数展開として表現することです。

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

::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)コメントに:を含めることはできません

25
dbenham

この ページは、 "::"を使うと特定の制約の下ではより速くなることを伝えます

7
mishal153

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

いくつかのテストとトリックの後、より良い解決策がより明白な解決策であるように思われます。

- >パーサーの整合性が失敗しないようにするための最良の方法は、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^ 
)
4
ZEE

James K、私が言ったことのかなりの部分で私が間違っていたのは残念です。私がしたテストは次のとおりです。

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

これはあなたの交替の説明を満たしていますが、「)は現時点では予期していなかった」というエラーで失敗します。エラーメッセージ。

私は今日さらにテストをしましたが、交互にすることはキーではありませんが、キーには偶数の行があり、二重コロン(::)で始まって二重コロンで終わらない2行がないようです。次の点を考慮してください。

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

これはうまくいきます!

しかしまたこれを考慮しなさい:

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

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

残念なことに、これはごくわずかですが、私はそれを使いたいのかどうかわからないのです。

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

3
Darin

このトピックに関する非常に詳細で分析的な議論は _ this _ ページにあります。

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

2
BiLaL