为什么CALL在此脚本中打印GOTO帮助消息?为什么后面的命令执行两次? [英] Why CALL prints the GOTO help message in this script?And why command after that are executed twice?
问题描述
- 您可以使用具有双倍展开的特殊符号访问标签。
- 不能使用包含
/?
的标签,因为GOTO
和CALL $>
确保执行两次,但第一次运行的输出可以在同一行重定向?
$ b@echo off
setlocal enableDelayedExpansion
setlabel = /?
call:%% label %%
echo ==测试消息以检查是否执行CALL或GOTO(或两者都不)命令==
exit / b 0
:/?
echo == CALL或GOTO已执行==
退出/ b 0
并输出:
将cmd.exe定向到批处理程序中的标记行。
GOTO标签
label将批处理程序中使用的文本字符串指定为标签。
您自己在一行上键入标签,以冒号开头。
如果启用命令扩展GOTO更改如下:
GOTO命令现在接受目标标签:EOF,它将控制
传送到当前批处理结束脚本文件。这是一个简单的方法来
退出批处理脚本文件,而不定义标签。类型CALL /?为
描述CALL命令的扩展,使这个功能
有用。
==测试消息以检查是否执行CALL或GOTO(或两个)命令==
==测试消息以检查是否执行CALL或GOTO(或两者都不)==
CALL
后的代码执行两次? ?
EDIT
这对我来说更难以解释:
@echo off
pre>
setlocal enableDelayedExpansion
setlabel =
set / ax = 1
call:%% label %%> nul
set / ax = x + 1
echo ---
echo - %x% -
echo ---
退出/ b 0
:/?
echo == CALL或GOTO已执行==
echo ==第一个参数:%1 ==
exit / b 0
输出为:
---
-3-
---
调用<$ c后的代码$ c> CALL
解决方案我总是感到惊讶,你仍然发现从来没有想到的东西来测试。
与Aacini相反,我不认为
:/?
这里作为有效的标签。 >
否则应该找到这样的标签。
我假设
CALL
的堆栈推送器函数,然后只需使用GOTO
跳转到标签。
扩展
命令本身未检测到
/?
,而是GOTO
命令。
goto
只显示帮助信息并完成,但由于/ code>已经将文件位置推送到堆栈,它的工作原理就像调用这个文件位置,然后返回到同一位置!
sethelp = ^ /?
call:myLabel %% help %%
这也显示了帮助, code> GOTO:myLabel /?会做。
但是这不会sethelp = /?
call:myLabel %% help %%
我想,GOTO只获取标签由CALL解析,其他参数移动到
%1,%2,...
可以解释为什么只有标签可以使用延迟展开两次。
@echo off
setlocal EnableDelayedExpansion
setlabel = myLabel
setpointer = ^!label ^!
call:!pointer!
exit / b
:myLabel
echo it works
Here's one interesting thread. And I tried to play with the two things discussed there.
- You can access labels with special symbols with double expansion.
- Labels that contain
/?
cannot be used becauseGOTO
andCALL
prints their help messages instead of execution.
And here's the result:
@echo off setlocal enableDelayedExpansion set "label=/?" call :%%label%% echo == Test message to check if the CALL or GOTO ( or neither ) command is executed == exit /b 0 :/? echo == CALL or GOTO has been executed == exit /b 0
And the output:
Directs cmd.exe to a labeled line in a batch program. GOTO label label Specifies a text string used in the batch program as a label. You type a label on a line by itself, beginning with a colon. If Command Extensions are enabled GOTO changes as follows: GOTO command now accepts a target label of :EOF which transfers control to the end of the current batch script file. This is an easy way to exit a batch script file without defining a label. Type CALL /? for a description of extensions to the CALL command that make this feature useful. == Test message to check if the CALL or GOTO ( or neither ) command is executed == == Test message to check if the CALL or GOTO ( or neither ) command is executed ==
And the code after the
CALL
is executed twice??EDIT
This is even more unexplainable to me:
@echo off setlocal enableDelayedExpansion set "label=/?" set /a x=1 call :%%label%% >nul set /a x=x+1 echo --- echo -%x%- echo --- exit /b 0 :/? echo == CALL or GOTO has been executed == echo == first argument : %1 == exit /b 0
The output is:
--- -3- ---
The code after the call of the
CALL
for sure is executed twice, but the output of the first run can be redirected in the same line?解决方案I'm always surprised, that you still found things that never came to my mind to test.
Contrary to Aacini, I don't believe that
:/?
acts here as a valid label.
Else this should find such a label.I suppose that the
CALL
command is internally composed of a stack pusher function and then just useGOTO
to jump to the label.And as you are using late expansion the
/?
isn't detected by theCALL
command itself, but by theGOTO
command.
Thegoto
shows only the help info and finished, but as thecall
has already pushed the fileposition to the stack it works like calling this filepostion and later return to the same location!set "help=^ /?" call :myLabel%%help%%
This shows also the help, like a
GOTO :myLabel /?
would do.
But this one don'tset "help=/?" call :myLabel %%help%%
I suppose, the GOTO gets only the label parsed by the CALL, the other parameters are moved to
%1, %2, ...
And this could explain why only the label can use delayed expansion two times.
@echo off setlocal EnableDelayedExpansion set "label=myLabel" set "pointer=^!label^!" call :!pointer! exit /b :myLabel echo it works
这篇关于为什么CALL在此脚本中打印GOTO帮助消息?为什么后面的命令执行两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!