如何递归扩展环境变量?

How to recursively expand an environment variable?

假设如下:

echo %MY_ENV_VAR% 扩展为 %USERPROFILE%\some\path
echo %USERPROFILE% 扩展为 C:\Users\MyUser

我的目标是在以下路径创建一个空文件:C:\Users\MyUser\some\path\FOO.txt.

我尝试了以下命令:type nul > %MY_ENV_VAR%\FOO.txt

不幸的是,输出是一个错误,指出系统找不到指定的路径。

我很确定这是因为 shell 没有递归扩展 %MY_ENV_VAR% 并且它试图找到以 %USERPROFILE% 开头的文字路径。

我怎样才能最好地实现我的目标?

rem Create the problem
set "MY_ENV_VAR=%%USERPROFILE%%\some\path"
echo %MY_ENV_VAR%

rem One solution
call set "MY_ENV_VAR=%MY_ENV_VAR%"
echo %MY_ENV_VAR%

call行,解析器会用变量的内容替换%MY_ENV_VAR%,生成

call set "MY_ENV_VAR=%USERPROFILE%\some\path"

执行此命令时,call 将强制执行第二个解析阶段,生成

set "MY_ENV_VAR=C:\Users\MyUser\some\path"

当然,如果USERPROFILE包含另一个变量引用,则必须重复该过程。

edited - 添加了 "solution" 到 "recursive" 问题并将所有代码放在子例程中。

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Create the problem
    set "_1first=c:\users"
    set "_2second=%%_1first%%\test"
    set "_3third=%%_2second%%\so & me\path"
    set "_4fourth=%%_3third%%"

    set "MY_ENV_VAR=%%_4fourth%%"

    echo inner variables
    echo -----------------------------
    set _
    echo -----------------------------
    echo(

    echo "MY_ENV_VAR = [%MY_ENV_VAR%]"
    call :expandInnerVariables MY_ENV_VAR
    echo "MY_ENV_VAR = [%MY_ENV_VAR%]"
    goto :eof

:expandInnerVariables varName
    setlocal enableextensions disabledelayedexpansion
    set "aux=="
    for /l %%i in (0 1 100) do (
        setlocal enabledelayedexpansion
        if "!%~1!"=="" (
            endlocal & goto :endExpand
        ) else for /f "delims=" %%a in ("=!%~1!") do (
            endlocal & call set "%~1%%a"
            setlocal enabledelayedexpansion 
            for /f "delims=" %%b in ("=!%~1!") do (
                endlocal & set "aux=%%b" & if %%a==%%b goto :endExpand
            )
        )
    )
    :endExpand
    endlocal & set "%~1%aux%"
    goto :eof