如何递归扩展环境变量?

时间:2015-04-20 23:56:34

标签: windows shell cmd

假设如下:

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%开头的文字路径。

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

1 个答案:

答案 0 :(得分:3)

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包含另一个变量引用,则必须重复该过程。

已修改 - 添加了"解决方案"到了#34;递归"问题并将所有代码放在子程序中。

@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