在cmd.exe中,如何让一个变量转义为setlocal命令?

pax*_*blo 8 windows scope cmd batch-file

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

但是,如果我真的希望其中一个变量可用,我对如何做到这一点感到茫然.

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

        @echo off
    :main
        setlocal enableextensions enabledelayedexpansion
        call :func
        echo.main_folder = %folder%
        endlocal
        goto :eof

    :func
        setlocal enableextensions enabledelayedexpansion
        set temp=%cd%
        set folder=
    :funcloop1
        if not "x%temp:~-1%"=="x\" (
            set folder=!temp:~-1!!folder!
            set temp=!temp:~1,-1!
            goto :funcloop1
        )
        echo.func_folder = %folder%
        endlocal
        goto :eof

当我运行它时,我得到输出:

func_folder = dir1
main_folder =
Run Code Online (Sandbox Code Playgroud)

你可以看到%folder%变量不能存活endlocal.但是,如果我setlocal/endlocal从函数中temp取消,则变量会污染命名空间main.

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

有没有办法cmd.exe允许一组选定的环境变量传播到外部范围,同时仍然阻止其他人影响它?换句话说,你可以同时拥有局部变量和返回变量吗?


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

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

Rob*_*ves 10

"对此的解决方案是利用CMD shell逐行评估变量的事实 - 因此将ENDLOCAL放在与SET语句相同的行上,得到我们想要的结果:"source:ss64.com

所以改变func的endlocal:到...

endlocal & set folder=%folder%
Run Code Online (Sandbox Code Playgroud)

......会让你得到你想要的行为.