asc*_*pfl 7 cmd batch-file syntax-error
我有以下代码片段:
if "%ARGV:~,1%"==":" echo %ARGV% begins with a colon.
Run Code Online (Sandbox Code Playgroud)
只要变量ARGV包含非空值,或者正确地说,它被定义,一切都按预期工作,因此如果字符串以ARGV冒号开头,echo则执行命令.
但是,只要我清除变量ARGV,就会出现语法错误:
Run Code Online (Sandbox Code Playgroud)echo was unexpected at this time.
这里发生了什么?语法完全正常,但为什么该命令行会失败?
即使是最有用的线程之一,Windows命令解释器(CMD.EXE)如何解析脚本?,因为这些事情没有提供这种行为的解释.
当我在命令提示符中直接执行相同操作时,一切都井然有序.此外,当我尝试使用延迟扩展时,也不会发生错误.
我的同伴回答了jeb回答 "Windows命令解释器(CMD.EXE)如何解析脚本?" 确实解释了这种行为.
我的同伴答案提供了有关%扩展如何工作以完全预测行为的必要细节.
如果您保持ECHO ON,那么您可以看到扩展的结果,并且错误消息是有意义的:
test.bat的
@echo on
@set "ARGV="
if "%ARGV:~,1%"==":" echo %ARGV% begins with a colon.
Run Code Online (Sandbox Code Playgroud)
- 输出 -
C:\test>test
echo was unexpected at this time.
C:\test>if "~,1" echo begins with a colon.
Run Code Online (Sandbox Code Playgroud)
我的答案解释扩展结果的重要规则是:
1)(百分比)从左边开始,扫描每个字符
%.如果发现那么
- 1.1(逃避
%) ...... 不相关- 1.2(扩展参数) ...... 不相关
- 1.3(扩展变量)
- 否则,如果禁用了命令扩展,则...... 不相关
- 否则,如果启用了命令扩展,则查看下一个字符串,在之前
%:或之前打破<LF>,并将其称为VAR(可能是一个空列表).如果VAR之前中断:,则后续字符%包含:在VAR中的最后一个字符并且之前中断%.
- 如果是下一个字符,
%则替换%VAR%为VAR的值(如果未定义VAR,则替换为空)并继续扫描- 否则,如果下一个字符是
:那么
- 如果未定义VAR,则删除
%VAR:并继续扫描.- ... 剩余无关紧要
从...开始
if "%ARGV:~,1%"==":" echo %ARGV% begins with a colon.
Run Code Online (Sandbox Code Playgroud)
变量扩展将以下所有字符串扩展为空,因为变量未定义:
%ARGV:
%"==":
%ARGV%
Run Code Online (Sandbox Code Playgroud)
你剩下的就是:
if "~,1" echo begins with a colon.
Run Code Online (Sandbox Code Playgroud)
它适用于延迟扩展,因为IF语句在延迟扩展之前被解析(在第2阶段的jeb答案中解释)
一切都在命令行中运行,因为命令行变量扩展在未定义变量时不会删除字符串.(在CmdLineParser中靠近底部的jeb答案中松散地解释:,Phase1(百分比))