我正在尝试在批处理脚本中一起使用setlocal enabledelayedexpansion
和cd
,这似乎不会将更改保留回shell。
我需要setlocal enabledelayedexpansion
的原因是我需要在脚本运行时动态扩展脚本中的变量。
考虑以下示例批处理文件:
a.bat
================================
setlocal enabledelayedexpansion
cd ..
上述批处理文件未按预期迁移到上一个目录!
检查this。
答案 0 :(得分:7)
Blorgbeard提供了一个解释,说明为什么在SETLOCAL之后发布的CD在ENDLOCAL之后不会持久存在(可能是明确的或隐含的)。
这是一个有趣的解决方法。 PUSHD堆栈与SETLOCAL / ENDLOCAL保存/恢复的环境无关。因此,以下简单序列将保留目录更改:
@echo off
setlocal
cd somePath
pushd .
endlocal
popd
如果somePath
不变,则不太有用 - 您可以在ENDLOCAL之后轻松发行CD。但如果somePath
是动态的,那么它会非常有用。
答案 1 :(得分:4)
问题是setlocal
导致当前目录更改对批处理文件是本地的。
请参阅setlocal /?
:
在批处理文件中开始环境更改的本地化。 <强>环境 发出SETLOCAL后所做的更改是批处理文件的本地更改。 必须发出ENDLOCAL才能恢复以前的设置。什么时候结束 到达批处理脚本时,将执行任何隐含的ENDLOCAL 由该批处理脚本发出的未完成的SETLOCAL命令。
当前目录包含在“环境变化”中。
尝试此操作,请注意它在批处理中为C:\
回显%CD%
,但当批处理退出时,当前目录仍会重置。
[11:42:00.17] C:\temp
> cat test.bat
@echo off
setlocal enabledelayedexpansion
cd ..
echo %CD%
[11:42:19.38] C:\temp
> test.bat
C:\
[11:42:23.00] C:\temp
>
答案 2 :(得分:0)
以下证明它有效 - 在根目录上的任何文件夹中启动批处理文件。
@echo off
setlocal enabledelayedexpansion
echo "%cd%"
cd ..
echo "%cd%"
pause
答案 3 :(得分:0)
在endlocal中的注册表中保存字符串。在win7 cmd上测试(skip = 2,可能因reg.exe的不同版本而异)
:: What: stash string in registry from cmd line, across endlocal barrier
:: PS. I added %RANDOM% to Windows-NT and Win95 command.com and still using it.
@echo off
set key="HKCU\Volatile Environment"
set keyname=stash%RANDOM%
set keytype=REG_SZ
setlocal ENABLEDELAYEDEXPANSION
::== Save string
set data_stash=Hello-%DATE%-%TIME%
echo Saving=%data_stash% in key=%keyname%
reg add %key% /v %keyname% /t %keytype% /d "%data_stash%" /f
endlocal
::== Read string
echo reg query %key% /v %keyname%
for /f "tokens=2* skip=2" %%a in ('reg query %key% /v %keyname%') do (
set data_unstashed=%%b
)
echo Read data_unstashed=%data_unstashed%
::== Delete stash
reg delete %key% /v %keyname% /f
编辑Stephan
另一种保存变量超出endlocal
的方法:
@echo off
set var1=hello
set var2=world
setlocal
echo previous: %var1%, %var2%
set var1=HELLO
set var2=WORLD
echo inside: %var1%, %var2%
endlocal & set "var1=%var1%" & set "var2=%var2%"
echo after: %var1%, %var2%
诀窍在于,由于解析,变量在 endlocal
生效之前已扩展,但在之后set
。
(对不起劫持你的答案,但这对评论来说也太大了)