Windows 在cmd.exe中,如何获取一个变量来转义setlocal命令?

Windows 在cmd.exe中,如何获取一个变量来转义setlocal命令?,windows,batch-file,scope,cmd,Windows,Batch File,Scope,Cmd,我经常在cmd.exe中使用setlocal,以避免临时变量污染环境变量空间(并确保命令扩展和延迟扩展都处于活动状态) 然而,如果我真的想让这些变量中的一个可用,我就不知道该怎么做 考虑以下代码,它为您提供当前目录的最终组件(因此c:\pax\dir1将为您提供dir1): 您可以看到%folder%变量在endlocal中不存在。但是,如果我从函数中退出setlocal/endlocal,则temp变量会污染main的命名空间 我知道我可以在func的末尾使用set temp=,这将删除环境变

我经常在
cmd.exe
中使用
setlocal
,以避免临时变量污染环境变量空间(并确保命令扩展和延迟扩展都处于活动状态)

然而,如果我真的想让这些变量中的一个可用,我就不知道该怎么做

考虑以下代码,它为您提供当前目录的最终组件(因此
c:\pax\dir1
将为您提供
dir1
):

您可以看到
%folder%
变量在
endlocal
中不存在。但是,如果我从函数中退出
setlocal/endlocal
,则
temp
变量会污染
main
的命名空间

我知道我可以在
func
的末尾使用
set temp=
,这将删除环境变量,但这不包括我已经在外部范围内使用该变量的情况(在这种情况下,它会被完全销毁)

cmd.exe
中是否有一种方法允许一组选定的环境变量传播到外部范围,同时仍防止其他变量影响它?换句话说,您可以同时拥有局部变量和返回变量吗


另外,请不要告诉我有更好的方法获得最终路径组件。这只是一个例子

事实上,您可以告诉我一个更好的方法,因为知道这一点很好,但它不会回答我的具体问题:-)

“解决方案是利用CMD shell逐行计算变量这一事实,因此将ENDLOCAL放在SET语句的同一行上会得到我们想要的结果:“source:

因此,将func:的endlocal更改为

endlocal & set folder=%folder%

…将为您提供所需的行为。

为了更好地阅读和格式化,您可以使用括号

call :func resultVar
echo(%resultVar%
goto :eof

:func 
setlocal
set var=2
(
  endlocal
  if "%1" NEQ "" set "%1=%var%"
  goto :eof
)
这是可行的,因为命令块将像单行一样展开。 解析器在执行命令块之前展开前两个阶段(百分比变量和转义字符)。
其他阶段会及时执行(如延迟扩展、第二阶段通过调用扩展等)

endlocal&&set aaa=%aaa%&set bbb=%bbb%
aaa
bbb
永久设置在
setlocal
之外,并将此设置保留在命令提示符中,以供其他批处理文件使用(对于exmaple,如果从另一个批处理文件调用了包含
setlocal
的批处理文件,则调用的批处理文件现在将具有
aaa
bbb


多亏有人解释了
endlocal&&set
。我浏览了无数个网站来解决这个直截了当的问题。

可能会再加上一些括号?@Ben据我所知,我不知道。使用的符号是一个命令分隔符,而不是运算符。不是说使用括号会有什么坏处,所以如果你愿意的话feel free.Brilliant.工作非常完美,包括多个
&&set
命令,允许多个变量转义。对不起,我的意思是说引号,而不是括号。
endlocal & set folder=%folder%
call :func resultVar
echo(%resultVar%
goto :eof

:func 
setlocal
set var=2
(
  endlocal
  if "%1" NEQ "" set "%1=%var%"
  goto :eof
)