繁体   English   中英

批处理文件不保留变量

[英]Batch file not keeping variables

为什么当CMD.exe终止时以下批处理文件不保留变量

@echo off
cmd /c "set var=hi"
if defined var (echo var is defined ("var=%var%")) else (echo var isn't defined)
pause
exit

有什么办法可以在保持变量的同时使用CMD / c? 为什么CMD / c不保留变量?

CMD / C启动一个新的子进程,该子进程有自己的环境空间,变量存储在内存中。 当该过程终止时,关联的环境空间将丢失,因此,您当然会丢失在那里定义的所有变量的定义。

子流程不可能直接访问或操纵父流程的变量。

如果执行的是简单命令并可以控制任何输出,则可以将定义写入stdout,并让FOR / F捕获输出,以便可以在父进程中设置值。 但是您将需要延迟扩展。

注意-这个例子很疯狂,但是应该可以理解

for /f "delims=" %%A in ('cmd /v:on /c "set var=hi&echo "var=!var!""') do set %%A

但是,要弄清引用的内容,需要转义的内容,事情可能会变得复杂起来。

如果您创建可以执行工作并使用FOR / F执行该批处理脚本,则可以简化工作。

测试棒

@echo off
set var1=hi
set var2=Ain't this fun
set var3=bye
setlocal enableDelayedExpansion
for %%V in (var1 var2 var3) do echo "%%V=!%%V!"

主蝙蝠

@echo off
for /f "delims=" %%A in ('cmd /c test.bat') do set %%A

实际上,FOR / F使用隐式CMD / C,并且您不再需要在命令中启用延迟扩展,因此您可以放弃显式CMD / C

@echo off
for /f "delims=" %%A in ('test.bat') do set %%A

如果您无法控制输出,则必须将值写入一个临时文件,然后主脚本即可加载该文件。 您可能会想编写一个定义变量的临时批处理脚本,但是然后冒着必须转义某些字符的风险,具体取决于变量的内容。 最安全的选择是使用延迟扩展写出变量名和值,并让父进程使用FOR / F加载它们。

test2.bat

@echo off
set var1=hi
set var2=Ain't this fun
set var3=bye
echo Here is some output that must be preserved, unrelated to variables
setlocal enableDelayedExpansion
(for %%V in (var1 var2 var3) do echo "%%V=!%%V!") >"%temp%\vars.temp"

主蝙蝠

@echo off
setlocal disableDelayedExpansion
cmd /c test2.bat
call "%temp%\vars.bat"
for /f "usebackq delims=" %%V in ("%temp%\vars.temp") do set "%%V"
del "%temp%\vars.temp"

请注意,在加载变量时,必须在主进程中禁用延迟扩展,否则将丢失任何! %%V展开时值中的字符。

但是,为了稳健起见,您应该执行一些操作以确保每个实例化都使用唯一的临时文件名,以便同时运行不会互相干扰。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM