从SETLOCAL动态返回多个变量

时间:2014-02-12 17:37:00

标签: variables batch-file dynamic return

我正在尝试以一种相当动态的方式来计算如何返回多个变量,我只是维护一个变量名列表,然后用循环执行ENDLOCAL“export”,但似乎是{ {1}}内部FOR循环中的扩展不会很快扩展。

我有什么遗漏或有其他方法可以实现这一目标吗?

示例代码:

!%%V!

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

这是一个 return 例程,用于保留范围内的变量。只需使用变量名称作为参数调用返回例程,然后调用endlocal %return%

例程:

:return [Variables...]
setlocal enabledelayedexpansion
set "return="
:_return
if "%~1"=="" endlocal & exit /b 1
if not defined %~1 goto __return
set "%~1=!%~1:"=""!"
set "%~1=!%~1:^=^^!"
set "%~1=!%~1:<=^<!"
set "%~1=!%~1:>=^>!"
set "%~1=!%~1:&=^&!"
set "%~1=!%~1:|=^|!"
:__return
set "return=!return!^&set ""%~1=!%~1!"""
if not "%~2"=="" shift & goto _return
setlocal disabledelayedexpansion
set "return=%return:!=^^^^^^^!%"
endlocal & endlocal & set "return=%return:""="%"
exit /b 0

用法:

call :return foo bar baz
endlocal %return%

实施例

只有变量a才会保留在范围之外。

@echo off
setlocal
echo Inside
set "a=1"
set "b=2"
echo(%a%
echo(%b%
call :return a
endlocal %return%
echo Outside
echo(%a%
echo(%b%
exit /b 0

:return [Variables...]
setlocal enabledelayedexpansion
set "return="
:_return
if "%~1"=="" endlocal & exit /b 1
if not defined %~1 goto __return
set "%~1=!%~1:"=""!"
set "%~1=!%~1:^=^^!"
set "%~1=!%~1:<=^<!"
set "%~1=!%~1:>=^>!"
set "%~1=!%~1:&=^&!"
set "%~1=!%~1:|=^|!"
:__return
set "return=!return!^&set ""%~1=!%~1!"""
if not "%~2"=="" shift & goto _return
setlocal disabledelayedexpansion
set "return=%return:!=^^^^^^^!%"
endlocal & endlocal & set "return=%return:""="%"
exit /b 0

代码中的问题

至于为什么你的代码没有按预期工作,是因为必须在运行endlocal命令之前扩展变量。阅读这篇关于托管命令行解析批处理脚本的优秀帖子: Answer: How does the Windows Command Interpreter (CMD.EXE) parse scripts?

更新

答案 1 :(得分:1)

:: "Export" %FOO%, %BAR%, and %BAZ% to calling context.
for %%a in ("endlocal" "FOO=%FOO%" "BAR=%BAR%" "BAZ=%BAZ%") do (
   if %%a equ "endlocal" (endlocal) else set %%a
)
exit /B

答案 2 :(得分:0)

怎么样

@ECHO OFF
SETLOCAL
FOR %%i IN (foo bar baz) DO SET $%%i=value:%%i
ECHO == initial values ===
SET $
SET "RETURN=$FOO $BAR"
CALL :demo
ECHO == after CALL modifying %return% ===
SET $

FOR %%i IN (foo bar baz) DO SET $%%i=value:%%i
ECHO == initial values ===
SET $

SET "RETURN=%RETURN% $BAZ"
CALL :demo
ECHO == after CALL modifying %return% ===
SET $

GOTO :eof

:demo
SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%i IN (foo bar baz) DO SET $%%i=modified:%%i
SET "$retvals="
FOR %%N IN (%RETURN%) DO SET "$retvals=!$retvals!^&set %%N=%%%%N%%"
CALL SET "$retvals=%$retvals%"

:: "Export" %FOO%, %BAR%, and %BAZ% to calling context.
endlocal%$retvals%

EXIT /B
GOTO :EOF

屈服

== initial values ===
$bar=value:bar
$baz=value:baz
$foo=value:foo
== after CALL modifying $FOO $BAR ===
$bar=modified:bar
$baz=value:baz
$foo=modified:foo
== initial values ===
$bar=value:bar
$baz=value:baz
$foo=value:foo
== after CALL modifying $FOO $BAR $BAZ ===
$bar=modified:bar
$baz=modified:baz
$foo=modified:foo

(我只是为了方便显示使用set

更改了varnames