ฉันควรใช้สไตล์ความคิดเห็นใดในไฟล์แบตช์


284

ฉันกำลังเขียนไฟล์แบตช์และฉันพบคู่มือผู้ใช้ซึ่งมีข้อมูลมาก สิ่งหนึ่งที่แสดงให้ฉันเห็นก็คือบรรทัดนั้นสามารถให้ความเห็นได้ไม่เพียงแค่กับREMแต่ยังรวม::ถึง มันบอกว่า:

ความคิดเห็นในรหัสแบตช์สามารถทำได้โดยใช้เครื่องหมายทวิภาคคู่ซึ่งเป็นการดีกว่าการใช้คำสั่ง REM เนื่องจากมีการประมวลผลป้ายกำกับก่อนที่จะเปลี่ยนสัญลักษณ์ ::<remark>ไม่มีปัญหา แต่rem <remark>ก่อให้เกิดข้อผิดพลาด

ทำไมทำเช่นนั้นคู่มือและตัวอย่างส่วนใหญ่ที่ฉันเห็นใช้REMคำสั่ง? ใช้::งานได้กับ Windows ทุกรุ่นหรือไม่


3
เพียงสำหรับบันทึกที่ฉันเคยเห็นปัญหาเมื่อ "REM" ถูกนำมาใช้เพื่อแสดงความคิดเห็นออกมาจากเส้นด้วยการเปลี่ยนเส้นทางภายใต้ Windows 98
ขุด

6
เช่นกันในแนวเดียวกันกับ @ ความคิดเห็นของ Digger: คู่มือการเชื่อมโยงสำหรับDOS ( command.exe) ไม่ได้cmd.exeที่NTประมวลผลคำสั่งที่พบบน Windows 2000 เป็นต้นไป rem <remark>ใช้งานได้ดีในช่วงหลัง (ตั้งแต่อย่างน้อย Windows XP) และREMเป็นกลุ่ม บริษัท ที่เป็นทางการและเป็นตัวเลือกที่ปลอดภัยที่สุดโดยรวม ในขณะที่::มีข้อดีของมันในที่สุดมันก็เป็นแฮ็คที่เป็นปัญหาภายใน(…)บล็อก
mklement0


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

2
หากมีการใช้ตัวแปรที่ล่าช้าในบรรทัด :: จะทำให้ข้อความแสดงข้อผิดพลาดบางอย่างเช่นไม่สามารถค้นหาดิสก์ไดรฟเฉพาะ ..... เพื่อการใช้ REM ที่ดีขึ้น
Scott Chu

2
:: ความคิดเห็นจะแยกวิเคราะห์และตัวละครพิเศษเช่น> | จบความคิดเห็นและข้อความต่อไปนี้จะไม่ถูกแสดงความคิดเห็น
mosh

4
@mosh ถูกต้อง ตัวอย่างเช่น%VAR%ตัวแปรจะถูกขยาย สมมติว่าคุณมี (ไม่ถูกต้อง) set TARGET=C:\Program Files (x86)\"foo.exe"และภายในDO(..)นิพจน์ที่คุณมี:: echo %TARGET%คุณจะได้รับข้อผิดพลาดเนื่องจากการ(x86)ขยายก่อนที่นิพจน์ทั้งหมดจะถูกประเมินนำไปสู่DO(..)นิพจน์ที่ไม่ถูกต้องและข้อผิดพลาดที่อธิบายไม่ได้มาก (ในกรณีนี้"\ Microsoft " ) คุณไม่จำเป็นต้องมี|หรือ>ในการแสดงออกของคุณ ::ไม่ได้แสดงความคิดเห็นที่แท้จริง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

แต่การที่จะหลีกเลี่ยงปัญหากับไฟล์ที่มีอยู่ชอบREM, REM.batหรือREM;.batเพียงแก้ไขเปลี่ยนแปลงที่ควรจะใช้

REM^;<space>Comment

และสำหรับตัวละคร;นั้นยังได้รับอนุญาตอย่างใดอย่างหนึ่ง;,:\/=

REM นั้นช้ากว่า::การทดสอบประมาณ6 เท่า (ทดสอบบน Win7SP1 พร้อมความคิดเห็น 100000 บรรทัด)
สำหรับการใช้งานปกติมันไม่สำคัญ (58 กับ 360 ต่อบรรทัดความคิดเห็น)

ความเห็นกับ ::

::เสมอรันเครื่องหมายปลายสาย

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

ป้ายกำกับและป้ายกำกับความคิดเห็น ::มีตรรกะพิเศษในบล็อกวงเล็บ
พวกเขามักจะครอบคลุมทั้งสองสายSO: คำสั่งไปที่ไม่ได้ทำงาน
ดังนั้นจึงไม่แนะนำสำหรับบล็อกวงเล็บเนื่องจากมักจะเป็นสาเหตุของข้อผิดพลาดทางไวยากรณ์

มีECHO ONการREMแสดงบรรทัด แต่ไม่มีบรรทัดที่แสดงความคิดเห็น::

ทั้งสองไม่สามารถคอมเม้นท์ที่เหลือของบรรทัดได้ดังนั้นความเรียบง่าย%~จะทำให้เกิดข้อผิดพลาดทางไวยากรณ์

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

3
@ LastStar007: การใช้รูปแบบการอ้างอิงทุกครั้งset "foo=bar"เป็นสิ่งที่ควรค่าแก่การแนะนำโดยทั่วไปเพราะเป็นรูปแบบที่แข็งแกร่งที่สุดที่จะแยกค่าอย่างชัดเจน ปัญหาที่คุณกำลังอธิบายอยู่ในตัวsetของพฤติกรรมและไม่เฉพาะ%= … =%ความคิดเห็น: ถ้าคุณใช้"var=val"quoting, setพิจารณาทุกอย่างที่เป็นไปตาม=ค่ารวมถึงช่องว่างต่อท้าย (ผ่านจุดสิ้นสุดของบรรทัดหรือถ้ามีจุดเริ่มต้นของ คำสั่ง inline ถัดไป)
mklement0

28

อีกทางเลือกหนึ่งคือการแสดงความคิดเห็นเป็นการขยายตัวแปรที่จะขยายออกไปเสมอ

ชื่อตัวแปรไม่สามารถมี=ยกเว้นสำหรับตัวแปรแบบไดนามิกที่ไม่มีเอกสารเหมือนและ
%=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

ผู้นำ=ไม่จำเป็น แต่ฉันชอบถ้าให้สมมาตร

มีข้อ จำกัด สองประการ:

1) ความคิดเห็นไม่สามารถมี %

2) ความคิดเห็นไม่สามารถมี :


ฮ่า ๆ! ทำให้มันเป็นหนึ่งในตัวแปรขนาดใหญ่! Genius! %=ExitCode%? เรียบร้อย เรียนรู้สิ่งใหม่ทุกวัน!
James K

คุณหมายความว่า=จำเป็นต้องมีการติดตาม แต่ดูเหมือนจะไม่เป็น
James K

4
@JamesK - ฉันใช้การลาก=เพื่อให้บางอย่างเช่น% = ExitCode =% เป็น "ความคิดเห็น" ไม่ใช่ตัวแปรแบบไดนามิก ฉันชอบที่จะใช้สไตล์ที่ใช้งานได้เสมอ (ยกเว้นข้อ จำกัด ที่ระบุไว้ที่ด้านล่างของคำตอบแน่นอน)
dbenham

ดูstackoverflow.com/a/20169219/1689714สำหรับการสำรวจตัวแปรแบบไดนามิก (เช่น% = ExitCode%% = ExitCodeAscii%% = C:%% = D:% __ ซีดี __% เป็นต้น) สิ่งที่พวกเขาหมายถึง มีการตั้งค่า ฯลฯ ..
Kieron Hardy

25

หลังจากที่ฉันรู้ว่าฉันสามารถใช้ป้ายกำกับ::เพื่อแสดงความคิดเห็นและใส่รหัสความคิดเห็น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
.
.
.

ใช้สิ่งที่เคยสัญกรณ์คุณต้องการ*'s, @' s ฯลฯ


คุณจัดการ/?สวิตช์เพื่อพิมพ์เมนูนี้อย่างไร
hoang

1
@hoang setlocal ENABLEDELAYEDEXPANSION <NEWLINE> set var =% ~ 1 <NEWLINE> echo พารามิเตอร์แรกคือ% 1 <NEWLINE> IF! VAR! == "/?" (GOTO การใช้งาน) <NEWLINE>: การใช้งาน <NEWLINE> echo blah blah .. <NEWLINE>
GL2014

16
การสลับโคลอนเดี่ยวและคู่จะต้องปวดหัวเมื่อคุณแทรกหรือลบแถว

@ GL2014 โดยทั่วไปคุณกำลังพูดว่า "คุณไม่ได้พิมพ์เมนูนี้ " โค้ดตัวอย่างของคุณต้องการคำนำหน้า echo กับแต่ละบรรทัดของบันทึกการใช้งาน คำตอบของ James K นั้นทำให้เข้าใจผิดว่ามันแสดงให้เห็นว่ามีวิธีการพิมพ์บันทึกการใช้งานตามที่เขียนไว้
Timbo

1
@ Timbo ฉันเขียนรูทีนย่อย ( :PrintHelp) สำหรับคำตอบนี้ที่ทำในสิ่งที่ @hoang ขอแน่นอน ฉันใช้ <HELP> และ </HELP> เป็นเครื่องหมาย แต่คุณสามารถใช้สิ่งที่เหมาะกับคุณ
cdlvcdlv

21

คำตอบนี้พยายามสรุปอย่างจริงจังของคำตอบที่ยอดเยี่ยมมากมายในหน้านี้:

คำตอบที่ยอดเยี่ยมของ jebสมควรได้รับการกล่าวถึงเป็นพิเศษเพราะมันเจาะลึกและครอบคลุมกรณีขอบจำนวนมาก
สะดุดตาเขาชี้ให้เห็นว่าตัวแปร misconstructed / พารามิเตอร์การอ้างอิงเช่น%~สามารถทำลายใด ๆของการแก้ปัญหาดังต่อไปนี้ - รวมทั้งREMเส้น


ความเห็นแบบเต็มบรรทัด - สไตล์ที่สนับสนุนโดยตรงเท่านั้น:

  • REM(หรือกรณีการเปลี่ยนแปลงดังกล่าว) เป็นความคิดเห็นอย่างเป็นทางการเพียงสร้างและเป็นทางเลือกที่ปลอดภัยที่สุด - ดูคำตอบที่เป็นประโยชน์ของโจอี้

  • ::คือแฮ็ค (ใช้กันอย่างแพร่หลาย)ซึ่งมีข้อดีและข้อเสีย :

    • ข้อดี :

      • ความชัดเจนของภาพและความง่ายในการพิมพ์
      • ความเร็วถึงแม้ว่ามันอาจจะไม่ค่อยได้เรื่อง - ดูคำตอบที่ดีของ Jebและร็อบแวนเดอร์โพสต์บล็อก Woude ยอดเยี่ยม
    • ข้อเสีย :

      • ภายใน(...)บล็อก::สามารถแบ่งคำสั่งและกฎสำหรับการใช้งานที่ปลอดภัยมีข้อ จำกัด และไม่ง่ายที่จะจำ - ดูด้านล่าง

หากคุณไม่ต้องการที่จะใช้::คุณมีตัวเลือกเหล่านี้:

  • อย่างใดอย่างหนึ่ง : เพื่อความปลอดภัยให้ยกเว้นใน(...)บล็อกและใช้ที่REMนั่นหรือไม่แสดงความคิดเห็นภายใน (...)ทั้งหมด
  • หรือ : จดจำกฎที่ จำกัด อย่างเจ็บปวดสำหรับการใช้งาน::ภายในอย่างปลอดภัย(...)ซึ่งสรุปไว้ในตัวอย่างต่อไปนี้:
@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]

ในบริบทนี้เราสามารถแยกแยะย่อยสองชนิด:

  • ความคิดเห็น EOL ([to-the-] end-of-line) ซึ่งสามารถวางไว้หลังคำสั่งและขยายไปถึงจุดสิ้นสุดของบรรทัดอย่างสม่ำเสมอ (อีกครั้งความเอื้อเฟื้อของคำตอบของ jeb ):

    • ver & REM <comment>ใช้ประโยชน์จากข้อเท็จจริงที่REMเป็นคำสั่งที่ถูกต้องและ&สามารถใช้เพื่อวางคำสั่งเพิ่มเติมหลังจากคำสั่งที่มีอยู่
    • ver & :: <comment>ใช้งานได้เช่นกัน แต่สามารถใช้งานได้นอก(...)บล็อกเท่านั้นเนื่องจากการใช้งานอย่างปลอดภัยมีข้อ จำกัด มากกว่าการใช้::แบบสแตนด์อโลน
  • ความคิดเห็นภายในบรรทัดซึ่งอยู่ระหว่างคำสั่งหลายคำสั่งในบรรทัดหรือในอุดมคติแม้จะอยู่ในคำสั่งที่กำหนด
    ความคิดเห็นภายในบรรทัดเป็นรูปแบบที่ยืดหยุ่นที่สุด (บรรทัดเดียว) และสามารถใช้นิยามได้ตามความคิดเห็น EOL

    • ver & REM^. ^<comment^> & verอนุญาตให้ใส่ความคิดเห็นระหว่างคำสั่ง (อีกครั้ง, คำอนุเคราะห์ของคำตอบของ jeb ), แต่ทราบวิธี<และ>จำเป็นที่จะต้อง^หลีกเลี่ยงเพราะตัวอักษรต่อไปนี้ ไม่สามารถใช้ตามที่เป็นอยู่:< > | (โดยที่ไม่ใช้ Escape &หรือ&&หรือ||เริ่มคำสั่งถัดไป )

    • %= <comment> =%ตามรายละเอียดในคำตอบที่ดีของ dbenhamเป็นรูปแบบที่มีความยืดหยุ่นมากที่สุดเพราะมันสามารถอยู่ภายในคำสั่ง (ในข้อโต้แย้ง)
      จะใช้ประโยชน์จากไวยากรณ์ตัวแปรการขยายตัวในทางที่ทำให้มั่นใจว่าการแสดงออกมักจะขยายไปยังสตริงที่ว่างเปล่า - ตราบใดที่ข้อความแสดงความคิดเห็นที่มีค่า%มิได้:
      ชอบREM, %= <comment> =%ทำงานได้ดีทั้งภายนอกและภายใน(...)บล็อก แต่มันก็เป็นขึ้นสายตาที่โดดเด่น; ข้อเสียเพียงอย่างเดียวคือมันยากที่จะพิมพ์ง่ายต่อการเข้าใจผิด syntactically และไม่เป็นที่รู้จักกันอย่างแพร่หลายซึ่งสามารถขัดขวางความเข้าใจของซอร์สโค้ดที่ใช้เทคนิค


ความคิดเห็นแบบหลายบรรทัด (บล็อกทั้งบรรทัด) :

  • คำตอบของ James Kแสดงวิธีใช้gotoข้อความและป้ายกำกับเพื่อกำหนดขอบเขตความคิดเห็นแบบหลายบรรทัดของความยาวและเนื้อหาโดยพลการ (ซึ่งในกรณีของเขาเขาใช้เพื่อเก็บข้อมูลการใช้งาน)

  • ซีคำตอบที่แสดงให้เห็นถึงวิธีการใช้"ฉลาก null"^เพื่อสร้างความคิดเห็นหลายสายถึงแม้ว่าจะต้องระมัดระวังที่จะยุติภายในบรรทัดทั้งหมดที่มี

  • การโพสต์บล็อกของ Rob van der Woudeพูดถึงอีกทางเลือกหนึ่งที่ค่อนข้างคลุมเครือซึ่งทำให้คุณสามารถจบไฟล์ด้วยจำนวนบรรทัดความคิดเห็นโดยพลการ : การเปิด(เพียงทำให้ทุกอย่างที่เกิดขึ้นหลังจากถูกเพิกเฉยตราบใดที่มันไม่มี^-escaped) )คือตราบใดที่บล็อกไม่ได้ปิด


[1] การใช้SET "foo=bar"เพื่อกำหนดตัวแปร - เช่นการใส่เครื่องหมายคำพูดคู่ล้อมรอบชื่อและ=ค่าที่รวมกัน - จำเป็นในคำสั่งเช่นSET "foo=bar" & REM Set foo to bar.เพื่อให้แน่ใจว่าสิ่งที่ตามมาคือค่าตัวแปรที่ตั้งใจ (จนถึงคำสั่งถัดไปในกรณีนี้ เว้นวรรคเดียว) ไม่ได้ตั้งใจเป็นส่วนหนึ่งของมัน
(นอกเหนือจากกัน: 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

คุณสามารถใช้ multiline พร้อมกับเคล็ดลับ "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

James K ฉันขอโทษฉันผิดในส่วนที่ยุติธรรมของสิ่งที่ฉันพูด การทดสอบที่ฉันทำมีดังต่อไปนี้:

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

สิ่งนี้ตรงกับคำอธิบายของคุณเกี่ยวกับการสลับ แต่ล้มเหลวด้วย ") ไม่คาดคิดในขณะนี้" ข้อความผิดพลาด.

ฉันทำการทดสอบไกลกว่านี้ในวันนี้และพบว่าการสลับไม่ใช่คีย์ แต่ปรากฏว่ากุญแจนั้นมีจำนวนคู่บรรทัดไม่มีการเรียงสองบรรทัดในแถวที่ขึ้นต้นด้วย double colons (: :) และไม่ลงท้ายด้วย double colons . พิจารณาสิ่งต่อไปนี้:

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

มันใช้งานได้!

แต่ให้พิจารณาสิ่งนี้ด้วย:

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

กฎของการมีความคิดเห็นเป็นจำนวนคู่ดูเหมือนว่าจะไม่ใช้เมื่อสิ้นสุดในคำสั่ง

น่าเสียดายที่มันเป็นกระรอกมากพอที่ฉันไม่แน่ใจว่าฉันต้องการใช้มัน

จริงๆทางออกที่ดีที่สุดและปลอดภัยที่สุดที่ฉันคิดคือถ้าโปรแกรมเช่น Notepad ++ อ่าน REM เป็น double colons แล้วจะเขียน double colons กลับเป็นคำสั่ง REM เมื่อบันทึกไฟล์ แต่ฉันไม่ได้ตระหนักถึงโปรแกรมดังกล่าวและฉันไม่ได้ตระหนักถึงปลั๊กอินใด ๆ สำหรับ Notepad ++ ที่ทำเช่นนั้น


2

การอภิปรายอย่างละเอียดและวิเคราะห์ในหัวข้อนี้มีอยู่ในหน้านี้

มันมีตัวอย่างรหัสและข้อดี / ข้อเสียของตัวเลือกที่แตกต่างกัน


1
คุณควรสรุปเนื้อหาของลิงก์ที่ให้ไว้ในคำตอบ มิฉะนั้นจะเรียกว่า "ลิงก์คำตอบเท่านั้น" และไม่มีประโยชน์อย่างสมบูรณ์หากลิงก์หายไป ในกรณีนี้หน้าชี้ไปที่ค่อนข้างตลกที่จะเลือกขึ้นอยู่กับการเพิ่มประสิทธิภาพความเร็วในการอ่านของไฟล์แบทช์จากฟลอปปี้ดิสก์ช้า :)
GreenAsJade

0

มีหลายวิธีในการแสดงความคิดเห็นในไฟล์แบทช์

1) ใช้ rem

นี่คือวิธีการอย่างเป็นทางการ ดูเหมือนว่าจะใช้เวลาในการดำเนินการนานกว่า::แม้ว่าจะเห็นได้ชัดว่าหยุดการแยกวิเคราะห์ก่อนกำหนดก่อนที่ carets จะถูกประมวลผล ร้อยละการขยายตัวเกิดขึ้นก่อนที่จะ rem และ::มีการระบุดังนั้นการใช้ร้อยละที่ไม่ถูกต้องเช่น%~จะทำให้เกิดข้อผิดพลาดถ้าร้อยละมีอยู่ ปลอดภัยที่จะใช้ที่ใดก็ได้ในบล็อกรหัส

2) การใช้ป้ายกำกับ:, ::หรือ:;อื่น ๆ

สำหรับ:: comment, ': ความคิดเห็น' เป็นชื่อป้ายกำกับที่ไม่ถูกต้องเนื่องจากเริ่มต้นด้วยอักขระที่ไม่ถูกต้อง มันก็โอเคที่จะใช้เครื่องหมายทวิภาคตรงกลางของฉลาก หากพื้นที่เริ่มต้นที่จุดเริ่มต้นของฉลากจะถูกลบออกจะกลายเป็น: label :labelหากมีช่องว่างหรือเครื่องหมายโคลอนปรากฏอยู่ตรงกลางของป้ายกำกับชื่อส่วนที่เหลือจะไม่ถูกแปลความหมายว่าหากมีป้ายกำกับสองป้าย:f:ooและ:f rrทั้งคู่จะถูกตีความเป็น:fและมีเพียงป้ายกำกับที่กำหนดในภายหลังในไฟล์เท่านั้นที่จะถูกข้ามไป ส่วนที่เหลือของฉลากแสดงความคิดเห็นได้อย่างมีประสิทธิภาพ มีทางเลือกหลายที่จะมี::ระบุไว้ที่นี่ คุณไม่สามารถgotoหรือฉลาก และจะไม่ทำงานcall::foogoto :foogoto ::foo

มันทำงานได้ดีนอกบล็อคโค้ด แต่หลังจากที่เลเบลในบล็อคโค้ดไม่ถูกต้องหรือไม่จะต้องมีบรรทัดคำสั่งที่ถูกต้อง :: commentเป็นอีกคำสั่งที่ใช้ได้จริง มันตีความมันเป็นคำสั่งและไม่ใช่ฉลาก; คำสั่งมีความสำคัญ ซึ่งเป็นคำสั่งให้ cd ไปยัง::โวลุ่มซึ่งจะทำงานหากคุณดำเนินการsubst :: C:\ไม่เช่นนั้นคุณจะได้รับข้อผิดพลาดของโวลุ่มไม่พบ นั่นเป็นเหตุผลว่าทำไม:;เนื้อหาจึงดีกว่าเพราะไม่สามารถตีความได้ด้วยวิธีนี้ดังนั้นจึงตีความเป็นป้ายกำกับแทนซึ่งทำหน้าที่เป็นคำสั่งที่ถูกต้อง นี่ไม่ใช่แบบเรียกซ้ำคือป้ายกำกับถัดไปไม่จำเป็นต้องมีคำสั่งหลังจากนั้น นั่นเป็นเหตุผลที่พวกเขามาในสอง

echo somethingคุณจำเป็นต้องให้คำสั่งที่ถูกต้องหลังจากเช่นฉลาก เลเบลในบล็อครหัสต้องมาพร้อมกับคำสั่งที่ถูกต้องอย่างน้อยหนึ่งคำดังนั้นบรรทัดจะมีสองคู่ คุณจะได้รับ)ข้อผิดพลาดที่ไม่คาดคิดหากมีช่องว่างหรือวงเล็บปิดในบรรทัดถัดไป หากมีช่องว่างระหว่างสอง::บรรทัดคุณจะได้รับข้อผิดพลาดทางไวยากรณ์ที่ไม่ถูกต้อง

คุณยังสามารถใช้ตัวดำเนินการคาเร็ตใน::ความคิดเห็นดังนี้:

@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มีคำสั่งที่ถูกต้องในบรรทัดถัดไป แต่ครั้งที่สองไม่ได้ดังนั้นจึงต้องการอย่างใดอย่างหนึ่งคือ& :;yes:;

3) การใช้ตัวแปรสภาพแวดล้อมที่ไม่ถูกต้อง

%= comment =%. ในแบตช์ไฟล์ตัวแปรสภาพแวดล้อมที่ไม่ได้กำหนดจะถูกลบออกจากสคริปต์ &ซึ่งทำให้มันเป็นไปได้ที่จะใช้พวกเขาในตอนท้ายของบรรทัดโดยไม่ต้องใช้ มันเป็นเรื่องปกติที่จะใช้ตัวแปรสภาพแวดล้อมที่ไม่ถูกต้องเช่นที่มีเครื่องหมายเท่ากับ ไม่จำเป็นต้องเพิ่มส่วนเกิน แต่ทำให้ดูสมมาตร นอกจากนี้ชื่อตัวแปรที่ขึ้นต้นด้วย "=" จะถูกสงวนไว้สำหรับตัวแปรแบบไดนามิกที่ไม่มีเอกสาร ตัวแปรแบบไดนามิกเหล่านั้นไม่สิ้นสุดด้วย "=" ดังนั้นเมื่อใช้ "=" ทั้งที่จุดเริ่มต้นและจุดสิ้นสุดของความคิดเห็นจะไม่มีความเป็นไปได้ของการปะทะกันของชื่อ ความคิดเห็นที่ไม่สามารถมีหรือ%:

@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) ในตอนท้ายของไฟล์ทุกอย่างหลังจากวงเล็บ unclosed คือความคิดเห็น

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