为什么不低于批处理文件保持变量时的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.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开始一个新的子进程,具有这样的变量存储在内存中它自己的环境空间。当这个过程终止时,相关的环境空间就会丢失,所以你当然会失去在那里定义的任何变量的定义。
用于子过程直接访问或操纵父进程的变量这是不可能的。
如果您要执行一个简单的命令,并拥有控制权的任何输出,那么你可以写的定义,标准输出,让FOR/F捕获输出,这样就可以在你的父进程设置的值。但是你需要延迟扩展。
注 - 这个例子是很空洞,但它应该得到点跨越
for /f "delims=" %%A in ('cmd /v:on /c "set var=hi&echo "var=!var!""') do set %%A
但事情可能会变得远为复杂,确定什么是引用,需要转义什么,...如果你创建一个批处理脚本,做的工作,并用FOR/F执行它
生命可以被简化。
test.bat的
@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!"
main.bat
@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"
注意,延迟扩展必须在主要的过程,当你加载变量被禁用,否则你将失去任何VALU字符!
es当3210扩展时。
但要健壮,你应该做的事情,以确保每个实例使用唯一的临时文件名,以便同时运行不揍海誓山盟。
在实际使用中,我会在批处理文件中执行调用'cmd/c“%〜0”',然后当批处理文件退出时,它将返回到主脚本。这是我能想到的'保持'批处理文件终止其自我的唯一方法。另外,如果CMD/c保存了变量,那么它将允许脚本的其余部分访问它设置的变量。你能想到任何其他的解决方案,可以让批处理文件自己调用它,同时保持它的环境空间吗? –
@BurnieRiley - 只需在脚本的开头添加一个'setlocal',脚本终止后,所有设置在脚本内部的变量都将被取消设置。 – SomethingDark
@BurnieRiley - 见我编辑的答案。 – dbenham
为什么你使用'cmd/c“set var = hi”'?这将在子进程中创建变量,并且变量将随着它而死。 – npocmaka
我很欣赏你使用的是MCVE(严重的是,这个标签超级难得),但为什么在这个世界上你会设置这样的变量? – SomethingDark
@SomethingDark,这只是一个例子。在实际使用中,我会在批处理文件中调用cmd/c“%〜0”',然后当批处理文件退出时,它将返回到主脚本。这是我能想到的'保持'批处理文件终止其自我的唯一方法。另外,如果CMD/c保存了变量,那么它将允许脚本的其余部分访问它设置的变量。长时间解释soz –