输入中的批次变量未更新 [英] Batch variable from input not being updated

查看:80
本文介绍了输入中的批次变量未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码段(省略了一些代码):

I have the following snippet (some code omitted):

REM Verify destination_folders.
FOR %%f in (%destination_folders%) do (
    IF NOT EXIST %%f (
        echo(
        echo Destination folder %%f does not exist. Is version %version% correct? Please update the script with your required parameters.
        SET /p continue="Do you want to abort the operation? [Y/N]:"
        echo cont=%continue%

        IF %continue:~0,1%==y (
            goto :eof
        )

        IF %continue:~0,1%==Y (
            goto :eof
        )
    )
)

问题在于,直到执行脚本后才分配变量continue.例如,如果continue是上一次执行中的N,然后我输入Y,它将不会更新它,因此分配后的回显将输出cont=N,尽管它应该是cont=Y.我在做什么错了?

The issue is that the variable continue is not being assigned until after the script has been executed. For example, if continue was N from the the previous execution and then I input Y it will not update it, hence the echo after the assignment will output cont=N although it should be cont=Y. What am I doing wrong?

推荐答案

您需要延迟扩展. setlocal enabledelayedexpansion在某处,并使用!continue!代替%continue%.问题在于%continue%在第一次读取整个括号代码块时会被扩展,因此在执行第一次循环时将其视为纯文本. !continue!保留其可变性,并在每次迭代时对其进行重新评估.

You need delayed expansion. setlocal enabledelayedexpansion somewhere, and use !continue! instead of %continue%. The problem is that %continue% is expanded as the entire parenthetical code block is read for the first time, so it's treated as flat text by the time for performs its first loop. !continue! retains its variability, and it's re-evaluated on each iteration.

您还可以像这样使用choiceif errorlevel来避免延迟扩展问题:

You can also avoid the delayed expansion problem by using choice and if errorlevel like this:

REM Verify destination_folders.
FOR %%f in (%destination_folders%) do (
    IF NOT EXIST "%%~f" (
        echo(
        echo Destination folder %%f does not exist. Is version %version% correct?
        echo Please update the script with your required parameters.

        choice /N /M "Do you want to abort the operation? [Y/N]: "
        if not errorlevel 2 goto :EOF
    )
)


要详细了解延迟扩展,请阅读help set文档的这一部分:


To learn in greater detail about delayed expansion, read this portion of the help set documentation:

最后,添加了对延迟的环境变量扩展的支持.默认情况下,始终禁用此支持,但可以通过/V命令行开关将其启用/禁用到CMD.EXE.看到CMD/?

Finally, support for delayed environment variable expansion has been added. This support is always disabled by default, but may be enabled/disabled via the /V command line switch to CMD.EXE. See CMD /?

延迟的环境变量扩展对于避免当前扩展的局限性很有用,当前扩展的局限性是在读取一行文本时而不是在执行该行时发生的.下面的示例演示了立即变量扩展的问题:

Delayed environment variable expansion is useful for getting around the limitations of the current expansion which happens when a line of text is read, not when it is executed. The following example demonstrates the problem with immediate variable expansion:

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "%VAR%" == "after" @echo If you see this, it worked
)

将永远不会显示该消息,因为在读取第一个IF语句时,BOTH IF语句中的%VAR%被替换了,因为它在逻辑上包括IF的主体,它是一个复合语句.因此,复合语句中的IF实际上是将"before"与"after"进行比较,这将永远是不相等的.同样,以下示例将无法正常工作:

would never display the message, since the %VAR% in BOTH IF statements is substituted when the first IF statement is read, since it logically includes the body of the IF, which is a compound statement. So the IF inside the compound statement is really comparing "before" with "after" which will never be equal. Similarly, the following example will not work as expected:

set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%

,因为它不会在当前目录中建立文件列表,而只是将LIST变量设置为找到的最后一个文件.同样,这是因为读取FOR语句时,%LIST%仅被扩展了一次,那时LIST变量为空.因此,我们正在执行的实际FOR循环是:

in that it will NOT build up a list of files in the current directory, but instead will just set the LIST variable to the last file found. Again, this is because the %LIST% is expanded just once when the FOR statement is read, and at that time the LIST variable is empty. So the actual FOR loop we are executing is:

for %i in (*) do set LIST= %i

只是将LIST设置为找到的最后一个文件.

which just keeps setting LIST to the last file found.

延迟的环境变量扩展使您可以在执行时使用其他字符(感叹号)来扩展环境变量.如果启用了延迟变量扩展,则可以将上述示例编写为如下所示:

Delayed environment variable expansion allows you to use a different character (the exclamation mark) to expand environment variables at execution time. If delayed variable expansion is enabled, the above examples could be written as follows to work as intended:

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" @echo If you see this, it worked
)

set LIST=
for %i in (*) do set LIST=!LIST! %i
echo %LIST%

这篇关于输入中的批次变量未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆