【问题标题】:Variable will not be set when using SET /P inside IF statement在 IF 语句中使用 SET /P 时不会设置变量
【发布时间】:2014-08-29 23:04:08
【问题描述】:

我编写了一个简单的批处理文件来在 Windows 7 下安装程序。set /p VAR=PROMPT 遇到了一个令人抓狂的错误:

输入丢弃的错误

这是一个简单的测试用例:

@echo off
setlocal

if exist "%USERPROFILE%\Documents" (
    set /p CONFIRM="Previous version is installed! Continue? (Y/n) "
    echo {%CONFIRM%}
)

if exist "%USERPROFILE%\Documents" (
    set /p CONFIRM="Previous version is installed! Continue? (Y/n) "
    echo {%CONFIRM%}
)

我运行它:

Previous version is installed! Continue? (Y/n) n
{}
Previous version is installed! Continue? (Y/n) n
{n}

请注意,当第一个 set /p 运行时,它实际上并没有保存我的输入!

提示修改错误(相关?)

我怀疑但不确定这是否与set /p 中更明显的错误有关,如果在定义if 块的括号内,它会截断第一个) 处的提示:

@echo off

if exist "%USERPROFILE%\Documents" (
    set /p CONFIRM=Previous version is installed! Continue? (Y/n)
    echo {%CONFIRM%}
)

至少这个版本捕获了我的输入,尽管它破坏了提示:

Previous version is installed! Continue? (Y/nn
{n}

解决方法?

有什么想法吗?还是set /p 有问题,我不能使用它?

编辑:结论

感谢@npocmaka 的链接和提示,我想我对发生的事情有了更好的了解:()-delimited 块内部的“解析时间”与“运行时间”与外部不同。因此这个例子:

@echo off

(
    set /p CONFIRM=^?
    echo {%CONFIRM%}
)

(
    set /p CONFIRM=^?
    echo {%CONFIRM%}
)

echo {%CONFIRM%}

运行时,很明显变量在块内获取预期值存在“延迟”:

?foo
{}
?bar
{foo}
{bar}

虽然延迟扩展有效,但我仍然认为这种行为与我读过的关于 set /p 应该如何工作的每一个描述都不一致,尽管这对于批处理文件的课程来说是一样的。似乎set /p 设置的变量在出现在块内时神奇地从解析时扩展except中逃脱。

我相信“prompt mangling”版本只能工作(排序),因为它无意中提前关闭了块,并且批处理文件处理器不会抱怨第二个不匹配的)

【问题讨论】:

  • 延迟扩展......
  • npocmaka,添加 setlocal EnableDelayedExpansion 并没有什么不同。虽然我怀疑这是一个解析器错误,但它显然与变量扩展没有任何关系。
  • 当使用延迟扩展时,变量应该用!而不是%括起来。至少如果它们在括号内。
  • 这里是 cmd 如何解析脚本的详尽概述:stackoverflow.com/a/4095133/388389。更多延迟扩展 - ss64.com/nt/delayedexpansion.htmlrobvanderwoude.com/variableexpansion.php
  • 我编辑了问题标题以反映问题,以便将来的读者更容易找到它。人们每天都在问需要延迟扩展的问题——这是最近最多的常见问题。

标签: windows batch-file windows-7 windows-7-x64


【解决方案1】:
@echo off
setlocal enableDelayedExpansion

if exist "%USERPROFILE%\Documents" (
    set /p CONFIRM="Previous version is installed! Continue? ^(Y/n^) "
    echo {!CONFIRM!}
)

if exist "%USERPROFILE%\Documents" (
    set /p CONFIRM="Previous version is installed! Continue? ^(Y/n^) "
    echo {!CONFIRM!}
)
Endlocal

这行得通吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 2021-09-14
    • 1970-01-01
    • 2021-02-02
    • 2017-04-26
    相关资源
    最近更新 更多