如果我没有设置enabledelayedexpansion
,if
block 内的变量值不会立即改变,直到出去。但如果我将其设置为打开,x
将在下一个命令中重置回之前的值。
setlocal enabledelayedexpansion
if defined x (
set yes=
set /p yes=Do you want to reset?
if !yes! == y set x=
)
if not defined x set /p x=X:
我想要的只是我不想要的
- 值在下一个命令时变回原样
- 值不会立即更改
谢谢@Mofi的回答。您的解决方案有效,但我必须首先删除 setlocal EnableExtensions DisableDelayedExpansion
我必须找出原因。因此,我们的教训是,我们无法立即读取刚刚在同一命令中设置的变量的新值,包括在没有 EnableDelayedExpansion
的扩展 block 内设置的变量。并且 EnableDelayedExpansion
必须在本地启用和结束,以免扰乱全局变量。我选择了带有 goto
的选项,但我使用 call
和 exit
来代替。
最佳答案
一个简单的解决方案是使用choice
而不是set/P
。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
if defined x (
%SystemRoot%\System32\choice.exe /C NY /N /M "Do you want to reset? [N/Y]"
if errorlevel 2 set "x="
)
if not defined x set /P "x=X: "
endlocal
自 Windows Vista 起,命令 CHOICE 默认可用,对于 Windows Server 2003 起的 Windows 服务器版本,默认情况下可用。 CHOICE 始终删除服务器两侧的所有普通空格和水平制表符。提示文本,然后在提示文本后自动添加一个空格。
一个真正安全的解决方案,其中 set/P
适用于任何用户输入,而不使用延迟环境变量扩展,如下所示,默认为 N
,用于用户不使用的情况输入任何内容。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
if not defined x goto PromptForX
set "yes=N"
set /P "yes=Do you want to reset? [N/Y] "
rem Remove all double quotes from user input string.
set "yes=%yes:"=%"
rem Has the user entered just one or more double quotes?
if not defined yes goto PromptForX
rem Now it is safe to compare the strings which cannot result anymore in a
rem syntax error caused by user input or doing something completely different
rem than the string comparison if the user input a command line which would
rem have changed this IF command line to a completely different command line.
if /I "%yes%" == "y" set "x="
:PromptForX
if not defined x set /P "x=X: "
endlocal
命令SET不会在提示文本中附加空格。批处理文件中定义的提示文本末尾必须有空格。
使用 set/P
并使用 delayed expansion 的另一个安全解决方案是:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
if defined x (
set "yes=N"
set /P "yes=Do you want to reset? [N/Y] "
setlocal EnableDelayedExpansion
if /I !yes! == y (endlocal & set "x=") else endlocal
)
if not defined x set /P "x=X: "
endlocal
首先使用endlocal
恢复之前的环境,然后Windows命令处理器执行set“x=”
,以在用户输入时取消定义此本地环境中的环境变量确实是 y
或 Y
,而只是在用户输入其他任何内容或根本没有输入任何内容时恢复之前的环境。有关运算符 &
的更多信息,另请参阅 Single line with multiple commands using Windows batch file。
我建议您还阅读 this answer,了解有关命令 SETLOCAL 和 ENDLOCAL 的详细信息,以及每次执行这两个命令时后台会发生什么。
有关这三种解决方案的完整说明,请阅读我的回答:
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
注意:在所有三个批处理文件中将最后一行从 endlocal
更改为 endlocal & set "x=%x%"
如果环境变量 x 也应该在演示批处理文件之外使用新值定义。
要了解所使用的命令及其工作原理,请打开 command prompt 窗口,在其中执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。
选择/?
回显/?
endlocal/?
转到/?
如果/?
雷姆/?
设置/?
setlocal/?
关于batch-file - 批处理 - 如何在启用了启用延迟扩展的情况下设置并保留下一个命令的变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61927255/