您有一个标准DELAYED EXPANSION
问题,在 SO 上无休止地讨论。
当批处理遇到"Block statement"
- 这通常是一个带括号的语句,分布在许多行上,例如你的,IF EXIST
那么整个语句被解析到右括号,此时,ANY被%var%
替换为该变量的值已解析
因此,您ECHO %olddirectory%
被替换为ECHO
因为在解析时olddirectory
没有值,另一方面,执行ECHO
将报告是在解析时设置的,因此被替换为ECHO is On/Off
progdata
echo Found %progdata%
echo Found C:\ProgramData
最简单的解决方法是将ECHO
语句移到block
IF EXIST "%progdata%" (
echo Found %progdata%
SET oldDirectory="%progdata%\%datetime%"
)
echo Olddirectory=%oldDirectory%
(我添加了,olddirectory=
以便echo
语句找到要回显的内容(如果olddirectory
未设置))
显示值的第二种最简单的方法是
IF EXIST "%progdata%" (
echo Found %progdata%
SET oldDirectory="%progdata%\%datetime%"
CALL echo %%oldDirectory%%
)
这里,ECHO
命令不是在 的上下文中展开IF
,而是在从上下文的CALL
运行时值获取其环境的IF
上下文中。
显示值的第三种最简单的方法是使用命令delayedexpansion
选项。setlocal
NT 批处理命令通常启动
@echo off
setlocal
它抑制echoing
并建立了一个局部环境。当在's 上下文endlocal
中到达文件或文件结尾时,将撤销对本地环境的任何更改。setlocal
如果一直遵循这个口头禅,我们就不会遇到这样的情况:一个变量由一个批次建立,而下一个批次的环境是“肮脏的”。考虑在同一cmd
会话中运行您的原始文件两次。progdata
,并且您正在建立的所有其他变量将在第二次到来时保持设置 - 因此olddirectory
可能由您的第一次调用设置,并保留该陈旧数据,如果由于某种原因它没有在第二次显式设置。setlocal
为您支持所有这些更改。
setlocal enabledelayedexpansion
为混合增加了额外的设施。而%var%
解析为 的PARSE-TIME值var
,如果delayedexpansion
已被调用,则!var!
解析为RUN-TIME值 - 因为它在FOR
循环中更改...
因此,添加
SETLOCAL ENABLEDELAYEDEXPANSION
在一个战略点(@echo off
直到你离开你的训练轮之后......)将允许你对显示进行简单的更改olddirectory
IF EXIST "%progdata%" (
echo Found %progdata%
SET oldDirectory="%progdata%\%datetime%"
echo !oldDirectory!
)