@echo off
goto :main
:func
echo ************************************************
echo ************************************************
echo ************************************************
echo ************************************************
echo ************************************************
echo ***********************************************
echo ***********************************************
echo ***********************************************
echo ************************************************
echo never go back to :main
echo This is the end of :func
exit /b
:main
:main
echo This is main
goto :func
exit /b
@echo off
goto main <- No use of colon
...
:main
:main <- Repeat label
echo At least one of the above labels are discoverable
REM main part done <- No use of colons in comments
这真的不是一个“错误”......因为它是设计使然。Windows 换行符被定义为“\r\n”...或“回车”和“换行”组合...而 *nix 风格更喜欢省略回车。在可能的情况下,您应该始终在 Windows 中的任何内容中使用“\r\n”。其他任何东西都可能被错误地解释......并导致大量意想不到的结果。
对于批处理文件,unix 行尾和 windows 行尾之间没有太大区别。
目前,在搜索标签时,只有一个已知的 GOTO 和 CALL 行为的故障。如果标签位于相对于当前文件位置的 512 字节边界上,则标签解析器无法找到标签。不同之处在于,因为回车用于内部行重置。请参阅当批处理文件具有 Unix 行结尾时调用和转到可能会失败
尽管使用了标签扫描器,但意外发现了更多问题,因为批处理解析器在百分比扩展阶段后直接删除了所有回车符。
显示问题的示例:
输出是
在文件中使用 (Unix line-ending)时,似乎会跳过批处理标签。
LF
.bat
有点,但是...
你必须是一个偏执狂
例如。:
这个怎么运作
使用 Unix 行结尾时,标签解析器将由于差一错误而跳过一些标签。这是由于解析器使用了 512 字节大小的块,并且假设行尾由两个字符表示
\r\n
,而不是一个\n
。当一个标签被错误地跳过时,下一个错误的跳过只能发生在 512 字节的偏移处。如果您在下一行复制标签,则复制的标签将在 512 个限制内,并且可以作为后备。此外,正如 @jeb 所展示的,解析器还将每个 512 字节大小的块的末尾误解为换行(以及以某种方式忽略冒号和这些伪行上的下一个文本之间的空白字符)。诸如 之类的注释
:: main section
可以触发解析器以某种方式将文本读取: main
为标签:main
。总之,解析器不仅可以跳过标签,还可以将注释和其他文本片段误解为标签。
为什么不坚持使用 dos 行结尾呢?
假设您的批处理脚本将保留其行尾并不总是安全的,尤其是在使用 Git 或通过 GitHub 共享内容时。对于跨平台项目来说,不关心行尾并假设 Unix 行尾作为公分母也很方便。
答案是:你可能会“走运”,它会与 LF 一起工作,但不要指望它。我们遇到了与原始请求者相同的问题。我们的过程最终会得到只有 LF 的 bat 文件,并且(抱歉找不到模式)有时标签会“找不到”,尽管很明显它在那里。必须转换为 CR-LF,或进行随机更改,直到它起作用!