【发布时间】: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.html 和 robvanderwoude.com/variableexpansion.php
-
我编辑了问题标题以反映问题,以便将来的读者更容易找到它。人们每天都在问需要延迟扩展的问题——这是最近最多的常见问题。
标签: windows batch-file windows-7 windows-7-x64