使用set / p更新批处理脚本的变量始终包含最后一个值

时间:2016-09-28 15:38:11

标签: windows batch-file cmd

我正在尝试使用set / p命令在循环内调整Windows批处理变量。键盘输入后,变量仍包含旧值。我已经读过通过set / p设置的变量只有本地范围。但我不明白“本地”在这里的含义。

@echo off
setlocal EnableDelayedExpansion

set a=4
echo Inital A: %a%

:LoopLabel
MODE | find %a% >nul 2>&1
IF %ERRORLEVEL% NEQ 0 (
    set /p "a=enter new a: "
    echo a=%a%
    goto LoopLabel
)

输出结果为:

Inital A: 4
enter new a: 5
a=4
enter new a: 6
a=5
enter new a: 7
a=6

有没有人有想法,我可以解释为什么会这样吗?

非常感谢, 强尼

1 个答案:

答案 0 :(得分:1)

在IF中执行代码是个问题。看看这个:

@echo off

set a=4
echo Inital A: %a%

:LoopLabel
MODE | find "%a%" >nul 2>&1
IF %ERRORLEVEL% EQU 0 goto stuff
    set /p "a=enter new a: "
    echo a=%a%
    goto LoopLabel
:stuff

set /p在IF之外执行,因此即使没有延迟扩展也能正常工作。

IF块中的所有命令同时(并行)进行评估,因此

echo a=%a%

运行,它不知道

指定的任何新值
set /p "a=enter new a: "

为了进一步说明,您的a确实包含新值,但echo a=%a%是使用旧值执行的。

一种解决方案是使用IF和标签来获得预期的程序流,同时避免在IF块中执行多步执行。

此外,除非您输入的值已被引用,或者在将find提供给%a%时在find附近添加引号,否则您将从a收到错误。

或者,您可以在set /p更改后,在echo a=%a% 值上使用延迟展开以获取其值。

要执行此操作,您需要更改

echo a=!a!

%1...%9

我批量知道的唯一变量范围是%* ed标签中的calla。否则,所有内容都是全局的,包括set /p设置的select all_rec.CaId, all_rec.Enrolled, all_rec.[Plan], all_rec.Category, all_rec.updateddate from (select distinct t1.CaId,t1.Enrolled,t1.[Plan],t2.Category,t2.updateddate from [table.one](nolock) t1 inner join [table.two](nolock) t2 on t1.CaId=t2.CaID where t1.coverageyear=2016 and right(t1.[Plan],2)<>left(t2.Category,2) ) as all_rec inner join (SELECT max(updateddate) AS LAST_DATE, CaId FROM [table.two](nolock) GROUP BY CaId) AS GRAB_DATE on (all_rec.Ca_Id = GRAB_DATE.Ca_Id) and (all_rec.updateddate = GRAB_DATE.updateddate) order by 5 desc