当我尝试在SHIFT
块内使用IF
时,我看到了一些意想不到的结果。使用这个:
@echo off
if "%1"=="/p" (
echo %1
shift
echo "shifted"
echo %1
)
我得到以下内容:
C:\>ex.bat /p HAI
/p
"shifted"
/p
但是,当我使用此代码时:
@echo off
echo %1
shift
echo "shifted"
echo %1
我明白了:
C:\>ex.bat /p HAI
/p
"shifted"
HAI
我需要第二个输出,但是在逻辑块中我可以循环它。我正试图在这里实现类似Jon的回答:Using parameters in batch files at DOS command line,但我遇到了一些麻烦。为什么会这样?
答案 0 :(得分:12)
这是预期的行为,因为在解析行时会扩展%1
,并且在一次传递中解析整个带括号的IF构造。因此,在解析新行之前,您无法看到SHIFT的结果,这在您离开括号内的块之后才会发生。
使用%var%
扩展环境变量时会出现同样的问题。使用环境变量,您可以使用SETLOCAL EnableDelayedExpansion
启用延迟展开,然后使用!var!
来解决问题。但是没有任何类似的方法可以使用延迟扩展来扩展参数。
编辑2013-06-21 - 没有类似的方法,但有一种相对较慢的简单方法。
您可以使用CALL并将%
加倍来强制重新排序该行。
@echo off
if "%1"=="/p" (
echo %1
shift
echo "shifted"
call echo %%1
)
strong <编辑2016-07-15
code in Vladislav's answer是一种不好的做法,因为它意味着您可以在使用GOTO离开后在一段代码中跳回来。这根本行不通。 GOTO立即杀死任何已解析的代码块。你也可以把弗拉迪斯拉夫的代码写成:
@echo off
if "%1"=="/p" (
goto :true
:true
echo "%1"
shift
echo shifted
echo "%1"
)
如果条件为FALSE,则跳过整个块。
如果条件为TRUE,则GOTO立即终止块,然后执行通常在:true标签(没有块上下文)。最后的额外)
被忽略了。
请注意,您无法使用此构造添加ELSE。以下内容未给出预期结果:
@echo off
if "%1"=="/p" (
goto :true
:true
echo "%1"
shift
echo shifted
echo "%1"
) else (
echo This will execute regardless whether arg1 is /p or not
)
如果为FALSE,则仅执行ELSE块。
如果为TRUE,则执行顶部块并立即终止。执行其余代码,) else (
行被忽略,因为)
起作用
如果解析器期望一个命令并且堆栈上没有活动的括号块,则作为REM。
我强烈建议您不要像我上面所示(或者像Vladislav所做的那样)在带括号的代码块中使用GOTO标签。
以下是做同样事情的更好(更简单且没有误导性)的方法:
@echo off
if not "%1"=="/p" goto :skip
echo "%1"
shift
echo shifted
echo "%1"
:skip
您可以使用一些额外的标签和GOTO支持IF / THEN / ELSE概念
@echo off
if not "%1"=="/p" goto :notP
echo "%1"
shift
echo shifted
echo "%1"
goto :endIf
:notP
echo not /p
:endIf
答案 1 :(得分:2)
实际上,如果阻止,你可以在外面执行转移:
@echo off
if "%1"=="/p" (
echo "%1"
goto:perform_shift;
:aftersift
echo "%1"
)
goto:end;
:perform_shift
shift
echo "shifted"
goto:aftersift;
:end
答案 2 :(得分:0)
移位命令在块内部没有立即生效,但在外部。
假设您想将参数读取为键值对:
:Parse
if "%1" equ "/p" (
set P=%2
shift
shift
)
if "%1" equ "/q" (
set Q=%2
shift
shift
)
if "%1" neq "" goto Parse
echo P: %P%
echo Q: %Q%
答案 3 :(得分:0)
要实现所需的目标,可以在移括号时使用附加的CALL
:
@echo off
if "%1"=="/p" (
echo %1
shift
echo "shifted"
call echo %%1
)
示例运行:
>ex.bat /p HAI
/p
"shifted"
HAI